2 * Copyright (c) 1999-2006 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.
32 #include <mach/mach.h>
36 #include <netinet/in.h>
39 #include "lu_overrides.h"
41 static pthread_mutex_t _rpc_lock
= PTHREAD_MUTEX_INITIALIZER
;
43 #define RPC_GET_NAME 1
47 #define ENTRY_SIZE sizeof(struct rpcent)
48 #define ENTRY_KEY _li_data_key_rpc
50 static struct rpcent
*
51 copy_rpc(struct rpcent
*in
)
53 if (in
== NULL
) return NULL
;
55 return (struct rpcent
*)LI_ils_create("s*4", in
->r_name
, in
->r_aliases
, in
->r_number
);
59 * Extract the next rpc entry from a kvarray.
62 extract_rpc(kvarray_t
*in
)
65 uint32_t d
, k
, kcount
;
68 if (in
== NULL
) return NULL
;
73 if (d
>= in
->count
) return NULL
;
76 memset(&tmp
, 0, ENTRY_SIZE
);
78 kcount
= in
->dict
[d
].kcount
;
80 for (k
= 0; k
< kcount
; k
++)
82 if (!strcmp(in
->dict
[d
].key
[k
], "r_name"))
84 if (tmp
.r_name
!= NULL
) continue;
85 if (in
->dict
[d
].vcount
[k
] == 0) continue;
87 tmp
.r_name
= (char *)in
->dict
[d
].val
[k
][0];
89 else if (!strcmp(in
->dict
[d
].key
[k
], "r_number"))
91 if (in
->dict
[d
].vcount
[k
] == 0) continue;
92 tmp
.r_number
= atoi(in
->dict
[d
].val
[k
][0]);
94 else if (!strcmp(in
->dict
[d
].key
[k
], "r_aliases"))
96 if (tmp
.r_aliases
!= NULL
) continue;
97 if (in
->dict
[d
].vcount
[k
] == 0) continue;
99 tmp
.r_aliases
= (char **)in
->dict
[d
].val
[k
];
103 if (tmp
.r_name
== NULL
) tmp
.r_name
= "";
104 if (tmp
.r_aliases
== NULL
) tmp
.r_aliases
= empty
;
106 return copy_rpc(&tmp
);
110 * Send a query to the system information daemon.
112 static struct rpcent
*
113 ds_getrpcbynumber(uint32_t number
)
115 static int proc
= -1;
118 snprintf(val
, sizeof(val
), "%u", number
);
119 return (struct rpcent
*)LI_getone("getrpcbynumber", &proc
, extract_rpc
, "number", val
);
123 * Send a query to the system information daemon.
125 static struct rpcent
*
126 ds_getrpcbyname(const char *name
)
128 static int proc
= -1;
130 return (struct rpcent
*)LI_getone("getrpcbyname", &proc
, extract_rpc
, "name", name
);
134 * Clean up / initialize / reinitialize the kvarray used to hold a list of all rpc entries.
139 LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY
));
149 * Get an entry from the getrpcent kvarray.
150 * Calls the system information daemon if the list doesn't exist (first call),
151 * or extracts the next entry if the list has been fetched.
153 static struct rpcent
*
156 static int proc
= -1;
158 return (struct rpcent
*)LI_getent("getrpcent", &proc
, extract_rpc
, ENTRY_KEY
, ENTRY_SIZE
);
162 * Checks if the system information daemon is running.
163 * If so, calls the appropriate fetch routine.
164 * If not, calls the appropriate "_old" routine.
165 * Places the result in thread-specific memory.
167 static struct rpcent
*
168 getrpc(const char *name
, uint32_t number
, int source
)
170 struct rpcent
*res
= NULL
;
171 struct li_thread_info
*tdata
;
173 tdata
= LI_data_create_key(ENTRY_KEY
, ENTRY_SIZE
);
174 if (tdata
== NULL
) return NULL
;
181 res
= ds_getrpcbyname(name
);
184 res
= ds_getrpcbynumber(number
);
187 res
= ds_getrpcent();
194 pthread_mutex_lock(&_rpc_lock
);
199 res
= copy_rpc(_old_getrpcbyname(name
));
202 res
= copy_rpc(_old_getrpcbynumber(number
));
205 res
= copy_rpc(_old_getrpcent());
210 pthread_mutex_unlock(&_rpc_lock
);
213 LI_data_recycle(tdata
, res
, ENTRY_SIZE
);
214 return (struct rpcent
*)tdata
->li_entry
;
218 getrpcbyname(const char *name
)
220 return getrpc(name
, -2, RPC_GET_NAME
);
225 getrpcbynumber(int number
)
227 getrpcbynumber(long number
)
233 return getrpc(NULL
, n
, RPC_GET_NUM
);
239 return getrpc(NULL
, -2, RPC_GET_ENT
);
243 setrpcent(int stayopen
)
245 if (_ds_running()) ds_setrpcent();
246 else _old_setrpcent(stayopen
);
252 if (_ds_running()) ds_endrpcent();
253 else _old_endrpcent();