Libinfo-278.0.3.tar.gz
[apple/libinfo.git] / lookup.subproj / lu_alias.c
1 /*
2 * Copyright (c) 1999-2006 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 * Alias lookup
26 * Copyright (C) 1989 by NeXT, Inc.
27 */
28
29 #include <stdlib.h>
30 #include <mach/mach.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <aliasdb.h>
34 #include <pthread.h>
35 #include "lu_utils.h"
36 #include "lu_overrides.h"
37
38 #define ENTRY_SIZE sizeof(struct aliasent)
39 #define ENTRY_KEY _li_data_key_alias
40
41 static pthread_mutex_t _alias_lock = PTHREAD_MUTEX_INITIALIZER;
42
43 static struct aliasent *
44 copy_alias(struct aliasent *in)
45 {
46 if (in == NULL) return NULL;
47
48 return (struct aliasent *)LI_ils_create("s4*4", in->alias_name, in->alias_members_len, in->alias_members, in->alias_local);
49 }
50
51 /*
52 * Extract the next alias entry from a kvarray.
53 */
54 static void *
55 extract_alias(kvarray_t *in)
56 {
57 struct aliasent tmp;
58 uint32_t d, k, kcount;
59 char *empty[1];
60
61 if (in == NULL) return NULL;
62
63 d = in->curr;
64 in->curr++;
65
66 if (d >= in->count) return NULL;
67
68 empty[0] = NULL;
69 memset(&tmp, 0, ENTRY_SIZE);
70
71 kcount = in->dict[d].kcount;
72
73 for (k = 0; k < kcount; k++)
74 {
75 if (!strcmp(in->dict[d].key[k], "alias_name"))
76 {
77 if (tmp.alias_name != NULL) continue;
78 if (in->dict[d].vcount[k] == 0) continue;
79
80 tmp.alias_name = (char *)in->dict[d].val[k][0];
81 }
82 else if (!strcmp(in->dict[d].key[k], "alias_members"))
83 {
84 if (tmp.alias_members != NULL) continue;
85 if (in->dict[d].vcount[k] == 0) continue;
86
87 tmp.alias_members_len = in->dict[d].vcount[k];
88 tmp.alias_members = (char **)in->dict[d].val[k];
89 }
90 else if (!strcmp(in->dict[d].key[k], "alias_local"))
91 {
92 if (in->dict[d].vcount[k] == 0) continue;
93 tmp.alias_local = atoi(in->dict[d].val[k][0]);
94 }
95 }
96
97 if (tmp.alias_name == NULL) tmp.alias_name = "";
98 if (tmp.alias_members == NULL) tmp.alias_members = empty;
99
100 return copy_alias(&tmp);
101 }
102
103 /*
104 * Send a query to the system information daemon.
105 */
106 static struct aliasent *
107 ds_alias_getbyname(const char *name)
108 {
109 static int proc = -1;
110
111 return (struct aliasent *)LI_getone("alias_getbyname", &proc, extract_alias, "name", name);
112 }
113
114 /*
115 * Clean up / initialize / reinitialize the kvarray used to hold a list of all rpc entries.
116 */
117 static void
118 ds_alias_endent(void)
119 {
120 LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY));
121 }
122
123 static void
124 ds_alias_setent(void)
125 {
126 ds_alias_endent();
127 }
128
129 /*
130 * Get an entry from the getrpcent kvarray.
131 * Calls the system information daemon if the list doesn't exist (first call),
132 * or extracts the next entry if the list has been fetched.
133 */
134 static struct aliasent *
135 ds_alias_getent(void)
136 {
137 static int proc = -1;
138
139 return (struct aliasent *)LI_getent("alias_getent", &proc, extract_alias, ENTRY_KEY, ENTRY_SIZE);
140 }
141
142 struct aliasent *
143 alias_getbyname(const char *name)
144 {
145 struct aliasent *res = NULL;
146 struct li_thread_info *tdata;
147
148 tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
149 if (tdata == NULL) return NULL;
150
151 if (_ds_running())
152 {
153 res = ds_alias_getbyname(name);
154 }
155 else
156 {
157 pthread_mutex_lock(&_alias_lock);
158 res = copy_alias(_old_alias_getbyname(name));
159 pthread_mutex_unlock(&_alias_lock);
160 }
161
162 LI_data_recycle(tdata, res, ENTRY_SIZE);
163 return (struct aliasent *)tdata->li_entry;
164
165 }
166
167 struct aliasent *
168 alias_getent(void)
169 {
170 struct aliasent *res = NULL;
171 struct li_thread_info *tdata;
172
173 tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
174 if (tdata == NULL) return NULL;
175
176 if (_ds_running())
177 {
178 res = ds_alias_getent();
179 }
180 else
181 {
182 pthread_mutex_lock(&_alias_lock);
183 res = copy_alias(_old_alias_getent());
184 pthread_mutex_unlock(&_alias_lock);
185 }
186
187 LI_data_recycle(tdata, res, ENTRY_SIZE);
188 return (struct aliasent *)tdata->li_entry;
189
190 }
191
192 void
193 alias_setent(void)
194 {
195 if (_ds_running()) ds_alias_setent();
196 else _old_alias_setent();
197 }
198
199 void
200 alias_endent(void)
201 {
202 if (_ds_running()) ds_alias_endent();
203 else _old_alias_endent();
204 }