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>
33 #include <netinet/in.h>
37 extern struct protoent
*_old_getprotobynumber();
38 extern struct protoent
*_old_getprotobyname();
39 extern struct protoent
*_old_getprotoent();
40 extern void _old_setprotoent();
41 extern void _old_endprotoent();
43 static pthread_mutex_t _protocol_lock
= PTHREAD_MUTEX_INITIALIZER
;
45 #define PROTO_GET_NAME 1
46 #define PROTO_GET_NUM 2
47 #define PROTO_GET_ENT 3
49 #define ENTRY_SIZE sizeof(struct protoent)
50 #define ENTRY_KEY _li_data_key_protocol
52 static struct protoent
*
53 copy_protocol(struct protoent
*in
)
55 if (in
== NULL
) return NULL
;
57 return (struct protoent
*)LI_ils_create("s*4", in
->p_name
, in
->p_aliases
, in
->p_proto
);
61 * Extract the next protocol entry from a kvarray.
64 extract_protocol(kvarray_t
*in
)
67 uint32_t d
, k
, kcount
;
70 if (in
== NULL
) return NULL
;
75 if (d
>= in
->count
) return NULL
;
78 memset(&tmp
, 0, ENTRY_SIZE
);
80 kcount
= in
->dict
[d
].kcount
;
82 for (k
= 0; k
< kcount
; k
++)
84 if (!strcmp(in
->dict
[d
].key
[k
], "p_name"))
86 if (tmp
.p_name
!= NULL
) continue;
87 if (in
->dict
[d
].vcount
[k
] == 0) continue;
89 tmp
.p_name
= (char *)in
->dict
[d
].val
[k
][0];
91 else if (!strcmp(in
->dict
[d
].key
[k
], "p_proto"))
93 if (in
->dict
[d
].vcount
[k
] == 0) continue;
94 tmp
.p_proto
= atoi(in
->dict
[d
].val
[k
][0]);
96 else if (!strcmp(in
->dict
[d
].key
[k
], "p_aliases"))
98 if (tmp
.p_aliases
!= NULL
) continue;
99 if (in
->dict
[d
].vcount
[k
] == 0) continue;
101 tmp
.p_aliases
= (char **)in
->dict
[d
].val
[k
];
105 if (tmp
.p_name
== NULL
) tmp
.p_name
= "";
106 if (tmp
.p_aliases
== NULL
) tmp
.p_aliases
= empty
;
108 return copy_protocol(&tmp
);
112 * Send a query to the system information daemon.
114 static struct protoent
*
115 ds_getprotobynumber(uint32_t number
)
117 static int proc
= -1;
120 snprintf(val
, sizeof(val
), "%u", number
);
121 return (struct protoent
*)LI_getone("getprotobynumber", &proc
, extract_protocol
, "number", val
);
125 * Send a query to the system information daemon.
127 static struct protoent
*
128 ds_getprotobyname(const char *name
)
130 static int proc
= -1;
132 return (struct protoent
*)LI_getone("getprotobyname", &proc
, extract_protocol
, "name", name
);
136 * Clean up / initialize / reinitialize the kvarray used to hold a list of all protocol entries.
141 LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY
));
150 static struct protoent
*
153 static int proc
= -1;
155 return (struct protoent
*)LI_getent("getprotoent", &proc
, extract_protocol
, ENTRY_KEY
, ENTRY_SIZE
);
158 static struct protoent
*
159 getproto(const char *name
, int number
, int source
)
161 struct protoent
*res
= NULL
;
162 struct li_thread_info
*tdata
;
164 tdata
= LI_data_create_key(ENTRY_KEY
, ENTRY_SIZE
);
165 if (tdata
== NULL
) return NULL
;
172 res
= ds_getprotobyname(name
);
175 res
= ds_getprotobynumber(number
);
178 res
= ds_getprotoent();
185 pthread_mutex_lock(&_protocol_lock
);
190 res
= copy_protocol(_old_getprotobyname(name
));
193 res
= copy_protocol(_old_getprotobynumber(number
));
196 res
= copy_protocol(_old_getprotoent());
201 pthread_mutex_unlock(&_protocol_lock
);
204 LI_data_recycle(tdata
, res
, ENTRY_SIZE
);
205 return (struct protoent
*)tdata
->li_entry
;
209 getprotobyname(const char *name
)
211 return getproto(name
, -2, PROTO_GET_NAME
);
215 getprotobynumber(int number
)
217 return getproto(NULL
, number
, PROTO_GET_NUM
);
223 return getproto(NULL
, -2, PROTO_GET_ENT
);
227 setprotoent(int stayopen
)
229 if (_ds_running()) ds_setprotoent();
230 else _old_setprotoent(stayopen
);
236 if (_ds_running()) ds_endprotoent();
237 else _old_endprotoent();