2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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
22 * @APPLE_LICENSE_HEADER_END@
26 * Copyright (C) 1989 by NeXT, Inc.
29 #include <mach/mach.h>
32 #include <rpc/types.h>
35 #include <netinet/in.h>
37 #include "_lu_types.h"
41 extern struct protoent
*_old_getprotobynumber();
42 extern struct protoent
*_old_getprotobyname();
43 extern struct protoent
*_old_getprotoent();
44 extern void _old_setprotoent();
45 extern void _old_endprotoent();
47 #define PROTO_GET_NAME 1
48 #define PROTO_GET_NUM 2
49 #define PROTO_GET_ENT 3
52 free_protocol_data(struct protoent
*p
)
56 if (p
== NULL
) return;
58 if (p
->p_name
!= NULL
) free(p
->p_name
);
59 aliases
= p
->p_aliases
;
62 while (*aliases
!= NULL
) free(*aliases
++);
68 free_protocol(struct protoent
*p
)
70 if (p
== NULL
) return;
71 free_protocol_data(p
);
76 free_lu_thread_info_protocol(void *x
)
78 struct lu_thread_info
*tdata
;
80 if (x
== NULL
) return;
82 tdata
= (struct lu_thread_info
*)x
;
84 if (tdata
->lu_entry
!= NULL
)
86 free_protocol((struct protoent
*)tdata
->lu_entry
);
87 tdata
->lu_entry
= NULL
;
90 _lu_data_free_vm_xdr(tdata
);
95 static struct protoent
*
96 extract_protocol(XDR
*xdr
)
99 int i
, j
, nvals
, nkeys
, status
;
102 if (xdr
== NULL
) return NULL
;
104 if (!xdr_int(xdr
, &nkeys
)) return NULL
;
106 p
= (struct protoent
*)calloc(1, sizeof(struct protoent
));
108 for (i
= 0; i
< nkeys
; i
++)
114 status
= _lu_xdr_attribute(xdr
, &key
, &vals
, &nvals
);
129 if ((p
->p_name
== NULL
) && (!strcmp("name", key
)))
134 p
->p_aliases
= (char **)calloc(nvals
, sizeof(char *));
135 for (j
= 1; j
< nvals
; j
++) p
->p_aliases
[j
-1] = vals
[j
];
139 else if (!strcmp("number", key
))
141 p
->p_proto
= atoi(vals
[0]);
147 for (; j
< nvals
; j
++) free(vals
[j
]);
152 if (p
->p_name
== NULL
) p
->p_name
= strdup("");
153 if (p
->p_aliases
== NULL
) p
->p_aliases
= (char **)calloc(1, sizeof(char *));
158 static struct protoent
*
159 copy_protocol(struct protoent
*in
)
164 if (in
== NULL
) return NULL
;
166 p
= (struct protoent
*)calloc(1, sizeof(struct protoent
));
168 p
->p_proto
= in
->p_proto
;
169 p
->p_name
= LU_COPY_STRING(in
->p_name
);
172 if (in
->p_aliases
!= NULL
)
174 for (len
= 0; in
->p_aliases
[len
] != NULL
; len
++);
177 p
->p_aliases
= (char **)calloc(len
+ 1, sizeof(char *));
178 for (i
= 0; i
< len
; i
++)
180 p
->p_aliases
[i
] = strdup(in
->p_aliases
[i
]);
187 recycle_protocol(struct lu_thread_info
*tdata
, struct protoent
*in
)
191 if (tdata
== NULL
) return;
192 p
= (struct protoent
*)tdata
->lu_entry
;
197 tdata
->lu_entry
= NULL
;
200 if (tdata
->lu_entry
== NULL
)
202 tdata
->lu_entry
= in
;
206 free_protocol_data(p
);
208 p
->p_proto
= in
->p_proto
;
209 p
->p_name
= in
->p_name
;
210 p
->p_aliases
= in
->p_aliases
;
215 static struct protoent
*
216 lu_getprotobynumber(long number
)
219 unsigned int datalen
;
221 static int proc
= -1;
227 if (_lookup_link(_lu_port
, "getprotobynumber", &proc
) != KERN_SUCCESS
)
233 number
= htonl(number
);
237 if (_lookup_all(_lu_port
, proc
, (unit
*)&number
, 1, &lookup_buf
, &datalen
)
243 datalen
*= BYTES_PER_XDR_UNIT
;
244 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
246 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
249 if (!xdr_int(&inxdr
, &count
))
252 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
259 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
263 p
= extract_protocol(&inxdr
);
265 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
270 static struct protoent
*
271 lu_getprotobyname(const char *name
)
274 unsigned int datalen
;
275 char namebuf
[_LU_MAXLUSTRLEN
+ BYTES_PER_XDR_UNIT
];
278 static int proc
= -1;
284 if (_lookup_link(_lu_port
, "getprotobyname", &proc
) != KERN_SUCCESS
)
290 xdrmem_create(&outxdr
, namebuf
, sizeof(namebuf
), XDR_ENCODE
);
291 if (!xdr__lu_string(&outxdr
, (_lu_string
*)&name
))
293 xdr_destroy(&outxdr
);
300 if (_lookup_all(_lu_port
, proc
, (unit
*)namebuf
,
301 xdr_getpos(&outxdr
) / BYTES_PER_XDR_UNIT
, &lookup_buf
, &datalen
)
304 xdr_destroy(&outxdr
);
308 xdr_destroy(&outxdr
);
310 datalen
*= BYTES_PER_XDR_UNIT
;
311 if ((lookup_buf
== NULL
) || (datalen
== 0)) return NULL
;
313 xdrmem_create(&inxdr
, lookup_buf
, datalen
, XDR_DECODE
);
316 if (!xdr_int(&inxdr
, &count
))
319 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
326 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
330 p
= extract_protocol(&inxdr
);
332 vm_deallocate(mach_task_self(), (vm_address_t
)lookup_buf
, datalen
);
340 struct lu_thread_info
*tdata
;
342 tdata
= _lu_data_create_key(_lu_data_key_protocol
, free_lu_thread_info_protocol
);
343 _lu_data_free_vm_xdr(tdata
);
353 static struct protoent
*
357 static int proc
= -1;
358 struct lu_thread_info
*tdata
;
360 tdata
= _lu_data_create_key(_lu_data_key_protocol
, free_lu_thread_info_protocol
);
363 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
364 _lu_data_set_key(_lu_data_key_protocol
, tdata
);
367 if (tdata
->lu_vm
== NULL
)
371 if (_lookup_link(_lu_port
, "getprotoent", &proc
) != KERN_SUCCESS
)
378 if (_lookup_all(_lu_port
, proc
, NULL
, 0, &(tdata
->lu_vm
), &(tdata
->lu_vm_length
)) != KERN_SUCCESS
)
384 /* mig stubs measure size in words (4 bytes) */
385 tdata
->lu_vm_length
*= 4;
387 if (tdata
->lu_xdr
!= NULL
)
389 xdr_destroy(tdata
->lu_xdr
);
392 tdata
->lu_xdr
= (XDR
*)calloc(1, sizeof(XDR
));
394 xdrmem_create(tdata
->lu_xdr
, tdata
->lu_vm
, tdata
->lu_vm_length
, XDR_DECODE
);
395 if (!xdr_int(tdata
->lu_xdr
, &tdata
->lu_vm_cursor
))
402 if (tdata
->lu_vm_cursor
== 0)
408 p
= extract_protocol(tdata
->lu_xdr
);
415 tdata
->lu_vm_cursor
--;
420 static struct protoent
*
421 getproto(const char *name
, int number
, int source
)
423 struct protoent
*res
= NULL
;
424 struct lu_thread_info
*tdata
;
426 tdata
= _lu_data_create_key(_lu_data_key_protocol
, free_lu_thread_info_protocol
);
429 tdata
= (struct lu_thread_info
*)calloc(1, sizeof(struct lu_thread_info
));
430 _lu_data_set_key(_lu_data_key_protocol
, tdata
);
438 res
= lu_getprotobyname(name
);
441 res
= lu_getprotobynumber(number
);
444 res
= lu_getprotoent();
454 res
= copy_protocol(_old_getprotobyname(name
));
457 res
= copy_protocol(_old_getprotobynumber(number
));
460 res
= copy_protocol(_old_getprotoent());
466 recycle_protocol(tdata
, res
);
467 return (struct protoent
*)tdata
->lu_entry
;
471 getprotobyname(const char *name
)
473 return getproto(name
, -2, PROTO_GET_NAME
);
477 getprotobynumber(int number
)
479 return getproto(NULL
, number
, PROTO_GET_NUM
);
485 return getproto(NULL
, -2, PROTO_GET_ENT
);
489 setprotoent(int stayopen
)
491 if (_lu_running()) lu_setprotoent();
492 else _old_setprotoent(stayopen
);
498 if (_lu_running()) lu_endprotoent();
499 else _old_endprotoent();