1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate *
4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate * with the License.
8*7c478bd9Sstevel@tonic-gate *
9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate *
14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate *
20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate */
26*7c478bd9Sstevel@tonic-gate
27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*7c478bd9Sstevel@tonic-gate
29*7c478bd9Sstevel@tonic-gate /*
30*7c478bd9Sstevel@tonic-gate * Public utilities and convenience calls (from the API spec):
31*7c478bd9Sstevel@tonic-gate * SLPFindScopes (queries for all known scopes)
32*7c478bd9Sstevel@tonic-gate * SLPEscape / Unescape
33*7c478bd9Sstevel@tonic-gate * SLPFree
34*7c478bd9Sstevel@tonic-gate * SLPSet/GetProperty
35*7c478bd9Sstevel@tonic-gate */
36*7c478bd9Sstevel@tonic-gate
37*7c478bd9Sstevel@tonic-gate #include <stdio.h>
38*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
39*7c478bd9Sstevel@tonic-gate #include <string.h>
40*7c478bd9Sstevel@tonic-gate #include <syslog.h>
41*7c478bd9Sstevel@tonic-gate #include <netdb.h>
42*7c478bd9Sstevel@tonic-gate #include <unistd.h>
43*7c478bd9Sstevel@tonic-gate #include <libintl.h>
44*7c478bd9Sstevel@tonic-gate #include <slp-internal.h>
45*7c478bd9Sstevel@tonic-gate
46*7c478bd9Sstevel@tonic-gate struct scopes_tree {
47*7c478bd9Sstevel@tonic-gate void *scopes;
48*7c478bd9Sstevel@tonic-gate int len;
49*7c478bd9Sstevel@tonic-gate };
50*7c478bd9Sstevel@tonic-gate
51*7c478bd9Sstevel@tonic-gate typedef SLPBoolean SLPScopeCallback(SLPHandle, const char *, SLPError, void *);
52*7c478bd9Sstevel@tonic-gate
53*7c478bd9Sstevel@tonic-gate static SLPSrvURLCallback collate_scopes;
54*7c478bd9Sstevel@tonic-gate static void collect_scopes(void *, VISIT, int, void *);
55*7c478bd9Sstevel@tonic-gate static SLPBoolean unpackSAAdvert_scope(slp_handle_impl_t *, char *,
56*7c478bd9Sstevel@tonic-gate SLPScopeCallback, void *,
57*7c478bd9Sstevel@tonic-gate void **, int *);
58*7c478bd9Sstevel@tonic-gate static SLPError SAAdvert_for_scopes(SLPHandle, void **);
59*7c478bd9Sstevel@tonic-gate static SLPError slp_unescape(const char *, char **, SLPBoolean, const char);
60*7c478bd9Sstevel@tonic-gate
61*7c478bd9Sstevel@tonic-gate /*
62*7c478bd9Sstevel@tonic-gate * Finds scopes according the the user administrative model.
63*7c478bd9Sstevel@tonic-gate */
SLPFindScopes(SLPHandle hSLP,char ** ppcScopes)64*7c478bd9Sstevel@tonic-gate SLPError SLPFindScopes(SLPHandle hSLP, char **ppcScopes) {
65*7c478bd9Sstevel@tonic-gate SLPError err;
66*7c478bd9Sstevel@tonic-gate char *reply, *unesc_reply;
67*7c478bd9Sstevel@tonic-gate void *stree = NULL;
68*7c478bd9Sstevel@tonic-gate void *collator = NULL;
69*7c478bd9Sstevel@tonic-gate
70*7c478bd9Sstevel@tonic-gate if (!hSLP || !ppcScopes) {
71*7c478bd9Sstevel@tonic-gate return (SLP_PARAMETER_BAD);
72*7c478bd9Sstevel@tonic-gate }
73*7c478bd9Sstevel@tonic-gate
74*7c478bd9Sstevel@tonic-gate /* first try administratively configured scopes */
75*7c478bd9Sstevel@tonic-gate if ((err = slp_administrative_scopes(ppcScopes, SLP_FALSE))
76*7c478bd9Sstevel@tonic-gate != SLP_OK) {
77*7c478bd9Sstevel@tonic-gate return (err);
78*7c478bd9Sstevel@tonic-gate }
79*7c478bd9Sstevel@tonic-gate
80*7c478bd9Sstevel@tonic-gate if (*ppcScopes) {
81*7c478bd9Sstevel@tonic-gate /* got scopes */
82*7c478bd9Sstevel@tonic-gate return (SLP_OK);
83*7c478bd9Sstevel@tonic-gate }
84*7c478bd9Sstevel@tonic-gate
85*7c478bd9Sstevel@tonic-gate /* DAs from active and passive discovery */
86*7c478bd9Sstevel@tonic-gate if ((err = slp_find_das("", &reply)) != SLP_OK &&
87*7c478bd9Sstevel@tonic-gate err != SLP_NETWORK_ERROR)
88*7c478bd9Sstevel@tonic-gate return (err);
89*7c478bd9Sstevel@tonic-gate
90*7c478bd9Sstevel@tonic-gate /* Unpack the reply */
91*7c478bd9Sstevel@tonic-gate if (reply) {
92*7c478bd9Sstevel@tonic-gate int numResults = 0; /* placeholder; not actually used */
93*7c478bd9Sstevel@tonic-gate
94*7c478bd9Sstevel@tonic-gate /* tag call as internal */
95*7c478bd9Sstevel@tonic-gate ((slp_handle_impl_t *)hSLP)->internal_call = SLP_TRUE;
96*7c478bd9Sstevel@tonic-gate
97*7c478bd9Sstevel@tonic-gate (void) slp_unpackSrvReply(
98*7c478bd9Sstevel@tonic-gate hSLP, reply, collate_scopes,
99*7c478bd9Sstevel@tonic-gate &stree, &collator, &numResults);
100*7c478bd9Sstevel@tonic-gate /* invoke last call */
101*7c478bd9Sstevel@tonic-gate (void) slp_unpackSrvReply(
102*7c478bd9Sstevel@tonic-gate hSLP, NULL, collate_scopes,
103*7c478bd9Sstevel@tonic-gate &stree, &collator, &numResults);
104*7c478bd9Sstevel@tonic-gate free(reply);
105*7c478bd9Sstevel@tonic-gate
106*7c478bd9Sstevel@tonic-gate /* revert internal call tag */
107*7c478bd9Sstevel@tonic-gate ((slp_handle_impl_t *)hSLP)->internal_call = SLP_FALSE;
108*7c478bd9Sstevel@tonic-gate }
109*7c478bd9Sstevel@tonic-gate
110*7c478bd9Sstevel@tonic-gate /* Finally, if no results yet, try SA discovery */
111*7c478bd9Sstevel@tonic-gate if (!stree) {
112*7c478bd9Sstevel@tonic-gate (void) SAAdvert_for_scopes(hSLP, &stree);
113*7c478bd9Sstevel@tonic-gate }
114*7c478bd9Sstevel@tonic-gate
115*7c478bd9Sstevel@tonic-gate if (!stree) {
116*7c478bd9Sstevel@tonic-gate /* found none, so just return "default" */
117*7c478bd9Sstevel@tonic-gate if (!(*ppcScopes = strdup("default"))) {
118*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "SLPFindScopes", "out of memory");
119*7c478bd9Sstevel@tonic-gate return (SLP_MEMORY_ALLOC_FAILED);
120*7c478bd9Sstevel@tonic-gate }
121*7c478bd9Sstevel@tonic-gate return (SLP_OK);
122*7c478bd9Sstevel@tonic-gate }
123*7c478bd9Sstevel@tonic-gate
124*7c478bd9Sstevel@tonic-gate /* we now have a btree, each leaf of which is a unique scope */
125*7c478bd9Sstevel@tonic-gate slp_twalk(stree, collect_scopes, 0, (void *) ppcScopes);
126*7c478bd9Sstevel@tonic-gate
127*7c478bd9Sstevel@tonic-gate /* unescape scopes list */
128*7c478bd9Sstevel@tonic-gate if ((err = slp_unescape(*ppcScopes, &unesc_reply, SLP_FALSE, '%'))
129*7c478bd9Sstevel@tonic-gate == SLP_OK) {
130*7c478bd9Sstevel@tonic-gate free(*ppcScopes);
131*7c478bd9Sstevel@tonic-gate *ppcScopes = unesc_reply;
132*7c478bd9Sstevel@tonic-gate } else {
133*7c478bd9Sstevel@tonic-gate free(unesc_reply);
134*7c478bd9Sstevel@tonic-gate }
135*7c478bd9Sstevel@tonic-gate
136*7c478bd9Sstevel@tonic-gate return (err);
137*7c478bd9Sstevel@tonic-gate }
138*7c478bd9Sstevel@tonic-gate
139*7c478bd9Sstevel@tonic-gate /*
140*7c478bd9Sstevel@tonic-gate * Finds scopes according to the adminstrative scoping model. A
141*7c478bd9Sstevel@tonic-gate * comma-seperated list of scopes is returned in *ppcScopes; the
142*7c478bd9Sstevel@tonic-gate * caller must free *ppcScopes.
143*7c478bd9Sstevel@tonic-gate * If the return_default parameter is true, and no scopes are found,
144*7c478bd9Sstevel@tonic-gate * *ppcScopes will be set to 'default', otherwise, *ppcScopes will
145*7c478bd9Sstevel@tonic-gate * be NULL. This helps simplify internal memory management.
146*7c478bd9Sstevel@tonic-gate */
slp_administrative_scopes(char ** ppcScopes,SLPBoolean return_default)147*7c478bd9Sstevel@tonic-gate SLPError slp_administrative_scopes(char **ppcScopes,
148*7c478bd9Sstevel@tonic-gate SLPBoolean return_default) {
149*7c478bd9Sstevel@tonic-gate const char *useScopes;
150*7c478bd9Sstevel@tonic-gate
151*7c478bd9Sstevel@tonic-gate *ppcScopes = NULL;
152*7c478bd9Sstevel@tonic-gate
153*7c478bd9Sstevel@tonic-gate /* @@@ first try DHCP */
154*7c478bd9Sstevel@tonic-gate /* next try the useScopes property */
155*7c478bd9Sstevel@tonic-gate useScopes = SLPGetProperty(SLP_CONFIG_USESCOPES);
156*7c478bd9Sstevel@tonic-gate
157*7c478bd9Sstevel@tonic-gate if (useScopes && *useScopes) {
158*7c478bd9Sstevel@tonic-gate if (!(*ppcScopes = strdup(useScopes))) {
159*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "SLPFindScopes", "out of memory");
160*7c478bd9Sstevel@tonic-gate return (SLP_MEMORY_ALLOC_FAILED);
161*7c478bd9Sstevel@tonic-gate }
162*7c478bd9Sstevel@tonic-gate return (SLP_OK);
163*7c478bd9Sstevel@tonic-gate }
164*7c478bd9Sstevel@tonic-gate
165*7c478bd9Sstevel@tonic-gate /* found none, so just return "default" */
166*7c478bd9Sstevel@tonic-gate if (return_default && !(*ppcScopes = strdup("default"))) {
167*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "SLPFindScopes", "out of memory");
168*7c478bd9Sstevel@tonic-gate return (SLP_MEMORY_ALLOC_FAILED);
169*7c478bd9Sstevel@tonic-gate }
170*7c478bd9Sstevel@tonic-gate return (SLP_OK);
171*7c478bd9Sstevel@tonic-gate }
172*7c478bd9Sstevel@tonic-gate
173*7c478bd9Sstevel@tonic-gate /*
174*7c478bd9Sstevel@tonic-gate * This function operates on the same btree as the collate_scopes().
175*7c478bd9Sstevel@tonic-gate * The difference is that this one is called for each
176*7c478bd9Sstevel@tonic-gate * SAAdvert recieved.
177*7c478bd9Sstevel@tonic-gate */
178*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
saadvert_callback(SLPHandle hp,char * scopes,SLPError err,void ** stree)179*7c478bd9Sstevel@tonic-gate static SLPBoolean saadvert_callback(SLPHandle hp, char *scopes,
180*7c478bd9Sstevel@tonic-gate SLPError err, void **stree) {
181*7c478bd9Sstevel@tonic-gate char *s, *tstate;
182*7c478bd9Sstevel@tonic-gate
183*7c478bd9Sstevel@tonic-gate if (err != SLP_OK) {
184*7c478bd9Sstevel@tonic-gate return (SLP_TRUE);
185*7c478bd9Sstevel@tonic-gate }
186*7c478bd9Sstevel@tonic-gate
187*7c478bd9Sstevel@tonic-gate for (
188*7c478bd9Sstevel@tonic-gate s = strtok_r((char *)scopes, ",", &tstate);
189*7c478bd9Sstevel@tonic-gate s;
190*7c478bd9Sstevel@tonic-gate s = strtok_r(NULL, ",", &tstate)) {
191*7c478bd9Sstevel@tonic-gate
192*7c478bd9Sstevel@tonic-gate char *ascope, **srch;
193*7c478bd9Sstevel@tonic-gate
194*7c478bd9Sstevel@tonic-gate if (!(ascope = strdup(s))) { /* no memory! */
195*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "collate_scopes",
196*7c478bd9Sstevel@tonic-gate "out of memory");
197*7c478bd9Sstevel@tonic-gate return (SLP_TRUE);
198*7c478bd9Sstevel@tonic-gate }
199*7c478bd9Sstevel@tonic-gate
200*7c478bd9Sstevel@tonic-gate srch = slp_tsearch(
201*7c478bd9Sstevel@tonic-gate (void *) ascope, stree,
202*7c478bd9Sstevel@tonic-gate (int (*)(const void *, const void *)) slp_strcasecmp);
203*7c478bd9Sstevel@tonic-gate if (*srch != ascope)
204*7c478bd9Sstevel@tonic-gate /* scope is already in there, so just free ascope */
205*7c478bd9Sstevel@tonic-gate free(ascope);
206*7c478bd9Sstevel@tonic-gate }
207*7c478bd9Sstevel@tonic-gate
208*7c478bd9Sstevel@tonic-gate return (SLP_TRUE);
209*7c478bd9Sstevel@tonic-gate }
210*7c478bd9Sstevel@tonic-gate
211*7c478bd9Sstevel@tonic-gate /*
212*7c478bd9Sstevel@tonic-gate * Generates an SAAdvert solicitation, and returns any scopes found
213*7c478bd9Sstevel@tonic-gate * from all recieved SAAdverts in stree. stree must be a btree
214*7c478bd9Sstevel@tonic-gate * structure.
215*7c478bd9Sstevel@tonic-gate */
SAAdvert_for_scopes(SLPHandle hSLP,void ** stree)216*7c478bd9Sstevel@tonic-gate static SLPError SAAdvert_for_scopes(SLPHandle hSLP, void **stree) {
217*7c478bd9Sstevel@tonic-gate SLPError err;
218*7c478bd9Sstevel@tonic-gate SLPBoolean sync_state;
219*7c478bd9Sstevel@tonic-gate slp_handle_impl_t *hp = (slp_handle_impl_t *)hSLP;
220*7c478bd9Sstevel@tonic-gate char *predicate;
221*7c478bd9Sstevel@tonic-gate const char *type_hint;
222*7c478bd9Sstevel@tonic-gate
223*7c478bd9Sstevel@tonic-gate /* get type hint, if set */
224*7c478bd9Sstevel@tonic-gate if ((type_hint = SLPGetProperty(SLP_CONFIG_TYPEHINT)) != NULL &&
225*7c478bd9Sstevel@tonic-gate *type_hint != 0) {
226*7c478bd9Sstevel@tonic-gate
227*7c478bd9Sstevel@tonic-gate size_t hintlen = strlen(type_hint);
228*7c478bd9Sstevel@tonic-gate size_t predlen = strlen("(service-type=)");
229*7c478bd9Sstevel@tonic-gate
230*7c478bd9Sstevel@tonic-gate /* check bounds */
231*7c478bd9Sstevel@tonic-gate if (hintlen > (SLP_MAX_STRINGLEN - predlen)) {
232*7c478bd9Sstevel@tonic-gate return (SLP_PARAMETER_BAD);
233*7c478bd9Sstevel@tonic-gate }
234*7c478bd9Sstevel@tonic-gate if (!(predicate = malloc(hintlen + predlen + 1))) {
235*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "SAAdvert_for_scopes",
236*7c478bd9Sstevel@tonic-gate "out of memory");
237*7c478bd9Sstevel@tonic-gate return (SLP_MEMORY_ALLOC_FAILED);
238*7c478bd9Sstevel@tonic-gate }
239*7c478bd9Sstevel@tonic-gate (void) strcpy(predicate, "(service-type=");
240*7c478bd9Sstevel@tonic-gate (void) strcat(predicate, type_hint);
241*7c478bd9Sstevel@tonic-gate (void) strcat(predicate, ")");
242*7c478bd9Sstevel@tonic-gate } else {
243*7c478bd9Sstevel@tonic-gate predicate = "";
244*7c478bd9Sstevel@tonic-gate type_hint = NULL;
245*7c478bd9Sstevel@tonic-gate }
246*7c478bd9Sstevel@tonic-gate
247*7c478bd9Sstevel@tonic-gate /* No callback for SLPFindScopes, so force synchronous mode only */
248*7c478bd9Sstevel@tonic-gate sync_state = hp->async;
249*7c478bd9Sstevel@tonic-gate hp->async = SLP_FALSE;
250*7c478bd9Sstevel@tonic-gate
251*7c478bd9Sstevel@tonic-gate if ((err = slp_start_call(hp)) != SLP_OK)
252*7c478bd9Sstevel@tonic-gate return (err);
253*7c478bd9Sstevel@tonic-gate
254*7c478bd9Sstevel@tonic-gate err = slp_packSrvRqst("service:service-agent", predicate, hp);
255*7c478bd9Sstevel@tonic-gate
256*7c478bd9Sstevel@tonic-gate if (err == SLP_OK)
257*7c478bd9Sstevel@tonic-gate err = slp_ua_common(hSLP, "",
258*7c478bd9Sstevel@tonic-gate (SLPGenericAppCB *)saadvert_callback,
259*7c478bd9Sstevel@tonic-gate stree,
260*7c478bd9Sstevel@tonic-gate (SLPMsgReplyCB *)unpackSAAdvert_scope);
261*7c478bd9Sstevel@tonic-gate
262*7c478bd9Sstevel@tonic-gate if (type_hint) {
263*7c478bd9Sstevel@tonic-gate free(predicate);
264*7c478bd9Sstevel@tonic-gate }
265*7c478bd9Sstevel@tonic-gate
266*7c478bd9Sstevel@tonic-gate if (err != SLP_OK)
267*7c478bd9Sstevel@tonic-gate slp_end_call(hp);
268*7c478bd9Sstevel@tonic-gate
269*7c478bd9Sstevel@tonic-gate /* restore sync state */
270*7c478bd9Sstevel@tonic-gate hp->async = sync_state;
271*7c478bd9Sstevel@tonic-gate
272*7c478bd9Sstevel@tonic-gate return (err);
273*7c478bd9Sstevel@tonic-gate }
274*7c478bd9Sstevel@tonic-gate
275*7c478bd9Sstevel@tonic-gate /*
276*7c478bd9Sstevel@tonic-gate * Unpack an SAAdvert and pass each set of scopes into cb.
277*7c478bd9Sstevel@tonic-gate */
278*7c478bd9Sstevel@tonic-gate /* ARGSUSED */
unpackSAAdvert_scope(slp_handle_impl_t * hSLP,char * reply,SLPScopeCallback cb,void * cookie,void ** collator,int * numResults)279*7c478bd9Sstevel@tonic-gate static SLPBoolean unpackSAAdvert_scope(slp_handle_impl_t *hSLP, char *reply,
280*7c478bd9Sstevel@tonic-gate SLPScopeCallback cb, void *cookie,
281*7c478bd9Sstevel@tonic-gate void **collator, int *numResults) {
282*7c478bd9Sstevel@tonic-gate char *surl, *scopes, *attrs;
283*7c478bd9Sstevel@tonic-gate SLPBoolean cont;
284*7c478bd9Sstevel@tonic-gate
285*7c478bd9Sstevel@tonic-gate if (!reply) {
286*7c478bd9Sstevel@tonic-gate cb(hSLP, NULL, SLP_LAST_CALL, cookie);
287*7c478bd9Sstevel@tonic-gate return (SLP_FALSE);
288*7c478bd9Sstevel@tonic-gate }
289*7c478bd9Sstevel@tonic-gate
290*7c478bd9Sstevel@tonic-gate /* tag call as internal; gets all scopes, regardless of maxResults */
291*7c478bd9Sstevel@tonic-gate hSLP->internal_call = SLP_TRUE;
292*7c478bd9Sstevel@tonic-gate
293*7c478bd9Sstevel@tonic-gate if (slp_unpackSAAdvert(reply, &surl, &scopes, &attrs) != SLP_OK) {
294*7c478bd9Sstevel@tonic-gate return (SLP_TRUE);
295*7c478bd9Sstevel@tonic-gate }
296*7c478bd9Sstevel@tonic-gate
297*7c478bd9Sstevel@tonic-gate cont = cb(hSLP, scopes, SLP_OK, cookie);
298*7c478bd9Sstevel@tonic-gate
299*7c478bd9Sstevel@tonic-gate /* revert internal_call tag */
300*7c478bd9Sstevel@tonic-gate hSLP->internal_call = SLP_FALSE;
301*7c478bd9Sstevel@tonic-gate
302*7c478bd9Sstevel@tonic-gate free(surl);
303*7c478bd9Sstevel@tonic-gate free(scopes);
304*7c478bd9Sstevel@tonic-gate free(attrs);
305*7c478bd9Sstevel@tonic-gate
306*7c478bd9Sstevel@tonic-gate return (cont);
307*7c478bd9Sstevel@tonic-gate }
308*7c478bd9Sstevel@tonic-gate
309*7c478bd9Sstevel@tonic-gate /*
310*7c478bd9Sstevel@tonic-gate * Creates a service request for finding DAs or SAs (based on 'filter'),
311*7c478bd9Sstevel@tonic-gate * and sends it to slpd, returning the reply in 'reply'.
312*7c478bd9Sstevel@tonic-gate */
slp_find_das(const char * filter,char ** reply)313*7c478bd9Sstevel@tonic-gate SLPError slp_find_das(const char *filter, char **reply) {
314*7c478bd9Sstevel@tonic-gate SLPError err;
315*7c478bd9Sstevel@tonic-gate char *msg, hostname[MAXHOSTNAMELEN];
316*7c478bd9Sstevel@tonic-gate
317*7c478bd9Sstevel@tonic-gate /* Try the cache first */
318*7c478bd9Sstevel@tonic-gate if (*reply = slp_find_das_cached(filter)) {
319*7c478bd9Sstevel@tonic-gate return (SLP_OK);
320*7c478bd9Sstevel@tonic-gate }
321*7c478bd9Sstevel@tonic-gate
322*7c478bd9Sstevel@tonic-gate /*
323*7c478bd9Sstevel@tonic-gate * create a find scopes message:
324*7c478bd9Sstevel@tonic-gate * this is a SrvRqst for the type directory-agent.sun.
325*7c478bd9Sstevel@tonic-gate */
326*7c478bd9Sstevel@tonic-gate /* use the local host's name for the scope */
327*7c478bd9Sstevel@tonic-gate (void) gethostname(hostname, MAXHOSTNAMELEN);
328*7c478bd9Sstevel@tonic-gate
329*7c478bd9Sstevel@tonic-gate err = slp_packSrvRqst_single(
330*7c478bd9Sstevel@tonic-gate SLP_SUN_DA_TYPE, hostname, filter, &msg, "en");
331*7c478bd9Sstevel@tonic-gate
332*7c478bd9Sstevel@tonic-gate if (err == SLP_OK) {
333*7c478bd9Sstevel@tonic-gate err = slp_send2slpd(msg, reply);
334*7c478bd9Sstevel@tonic-gate free(msg);
335*7c478bd9Sstevel@tonic-gate }
336*7c478bd9Sstevel@tonic-gate
337*7c478bd9Sstevel@tonic-gate /* Add the reply to the cache */
338*7c478bd9Sstevel@tonic-gate if (err == SLP_OK) {
339*7c478bd9Sstevel@tonic-gate slp_put_das_cached(filter, *reply, slp_get_length(*reply));
340*7c478bd9Sstevel@tonic-gate }
341*7c478bd9Sstevel@tonic-gate
342*7c478bd9Sstevel@tonic-gate return (err);
343*7c478bd9Sstevel@tonic-gate }
344*7c478bd9Sstevel@tonic-gate
345*7c478bd9Sstevel@tonic-gate /*
346*7c478bd9Sstevel@tonic-gate * This is called for each URL entry in the DA service reply (sun private).
347*7c478bd9Sstevel@tonic-gate * Contained within the cookie is a btree, to which it adds new
348*7c478bd9Sstevel@tonic-gate * scopes from the URL entry. The scopes are retrieved from the btree
349*7c478bd9Sstevel@tonic-gate * by traversing the tree in SLPFindScopes().
350*7c478bd9Sstevel@tonic-gate * SLPHandle h is NULL, so don't touch it!
351*7c478bd9Sstevel@tonic-gate */
352*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
collate_scopes(SLPHandle h,const char * u,unsigned short lifetime,SLPError errCode,void * cookie)353*7c478bd9Sstevel@tonic-gate static SLPBoolean collate_scopes(SLPHandle h, const char *u,
354*7c478bd9Sstevel@tonic-gate unsigned short lifetime,
355*7c478bd9Sstevel@tonic-gate SLPError errCode, void *cookie) {
356*7c478bd9Sstevel@tonic-gate SLPSrvURL *surl;
357*7c478bd9Sstevel@tonic-gate char *s, *tstate, *p, *url;
358*7c478bd9Sstevel@tonic-gate void **collator = cookie;
359*7c478bd9Sstevel@tonic-gate
360*7c478bd9Sstevel@tonic-gate if (errCode != SLP_OK)
361*7c478bd9Sstevel@tonic-gate return (SLP_TRUE);
362*7c478bd9Sstevel@tonic-gate
363*7c478bd9Sstevel@tonic-gate /* dup url so as not to corrupt da cache */
364*7c478bd9Sstevel@tonic-gate if (!(url = strdup(u))) {
365*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "collate_scopes", "out of memory");
366*7c478bd9Sstevel@tonic-gate return (SLP_FALSE);
367*7c478bd9Sstevel@tonic-gate }
368*7c478bd9Sstevel@tonic-gate
369*7c478bd9Sstevel@tonic-gate /* parse url into a SLPSrvURL struct */
370*7c478bd9Sstevel@tonic-gate if (SLPParseSrvURL(url, &surl) != SLP_OK)
371*7c478bd9Sstevel@tonic-gate return (SLP_TRUE); /* bad URL; skip it */
372*7c478bd9Sstevel@tonic-gate
373*7c478bd9Sstevel@tonic-gate /* collate the scopes using the btree stree->scopes: */
374*7c478bd9Sstevel@tonic-gate /* skip the 'scopes=' part */
375*7c478bd9Sstevel@tonic-gate if (!(p = strchr(surl->s_pcSrvPart, '='))) {
376*7c478bd9Sstevel@tonic-gate free(surl);
377*7c478bd9Sstevel@tonic-gate return (SLP_TRUE); /* bad URL; skip it */
378*7c478bd9Sstevel@tonic-gate }
379*7c478bd9Sstevel@tonic-gate p++;
380*7c478bd9Sstevel@tonic-gate
381*7c478bd9Sstevel@tonic-gate for (
382*7c478bd9Sstevel@tonic-gate s = strtok_r(p, ",", &tstate);
383*7c478bd9Sstevel@tonic-gate s;
384*7c478bd9Sstevel@tonic-gate s = strtok_r(NULL, ",", &tstate)) {
385*7c478bd9Sstevel@tonic-gate
386*7c478bd9Sstevel@tonic-gate char *ascope, **srch;
387*7c478bd9Sstevel@tonic-gate
388*7c478bd9Sstevel@tonic-gate if (!(ascope = strdup(s))) { /* no memory! */
389*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "collate_scopes",
390*7c478bd9Sstevel@tonic-gate "out of memory");
391*7c478bd9Sstevel@tonic-gate free(surl);
392*7c478bd9Sstevel@tonic-gate return (SLP_TRUE);
393*7c478bd9Sstevel@tonic-gate }
394*7c478bd9Sstevel@tonic-gate
395*7c478bd9Sstevel@tonic-gate srch = slp_tsearch(
396*7c478bd9Sstevel@tonic-gate (void *) ascope, collator,
397*7c478bd9Sstevel@tonic-gate (int (*)(const void *, const void *)) slp_strcasecmp);
398*7c478bd9Sstevel@tonic-gate if (*srch != ascope)
399*7c478bd9Sstevel@tonic-gate /* scope is already in there, so just free ascope */
400*7c478bd9Sstevel@tonic-gate free(ascope);
401*7c478bd9Sstevel@tonic-gate }
402*7c478bd9Sstevel@tonic-gate
403*7c478bd9Sstevel@tonic-gate free(url);
404*7c478bd9Sstevel@tonic-gate free(surl);
405*7c478bd9Sstevel@tonic-gate
406*7c478bd9Sstevel@tonic-gate return (SLP_TRUE);
407*7c478bd9Sstevel@tonic-gate }
408*7c478bd9Sstevel@tonic-gate
409*7c478bd9Sstevel@tonic-gate /*
410*7c478bd9Sstevel@tonic-gate * Each time we visit a node for the last time, copy that scope into
411*7c478bd9Sstevel@tonic-gate * the scope collection and free the scope string and the node.
412*7c478bd9Sstevel@tonic-gate */
413*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/
collect_scopes(void * node,VISIT order,int level,void * cookie)414*7c478bd9Sstevel@tonic-gate static void collect_scopes(void *node, VISIT order, int level, void *cookie) {
415*7c478bd9Sstevel@tonic-gate char **scopes = (char **)cookie;
416*7c478bd9Sstevel@tonic-gate
417*7c478bd9Sstevel@tonic-gate if (order == endorder || order == leaf) {
418*7c478bd9Sstevel@tonic-gate char *s = *(char **)node;
419*7c478bd9Sstevel@tonic-gate slp_add2list(s, scopes, SLP_FALSE);
420*7c478bd9Sstevel@tonic-gate free(s);
421*7c478bd9Sstevel@tonic-gate free(node);
422*7c478bd9Sstevel@tonic-gate }
423*7c478bd9Sstevel@tonic-gate }
424*7c478bd9Sstevel@tonic-gate
SLPFree(void * pvMem)425*7c478bd9Sstevel@tonic-gate void SLPFree(void *pvMem) {
426*7c478bd9Sstevel@tonic-gate if (pvMem)
427*7c478bd9Sstevel@tonic-gate free(pvMem);
428*7c478bd9Sstevel@tonic-gate }
429*7c478bd9Sstevel@tonic-gate
430*7c478bd9Sstevel@tonic-gate /*
431*7c478bd9Sstevel@tonic-gate * Escape / Unescape
432*7c478bd9Sstevel@tonic-gate */
433*7c478bd9Sstevel@tonic-gate
434*7c478bd9Sstevel@tonic-gate #define isBadTagChar(c) ((c) == '*' || (c) == '_' || \
435*7c478bd9Sstevel@tonic-gate (c) == '\n' || (c) == '\t' || (c) == '\r')
436*7c478bd9Sstevel@tonic-gate
437*7c478bd9Sstevel@tonic-gate #define isReserved(c) ((c) <= 31 || (c) == '(' || (c) == ')' || \
438*7c478bd9Sstevel@tonic-gate (c) == ',' || (c) == '\\' || (c) == '!' || \
439*7c478bd9Sstevel@tonic-gate (c) == '<' || (c) == '=' || (c) == '>' || \
440*7c478bd9Sstevel@tonic-gate (c) == '~')
441*7c478bd9Sstevel@tonic-gate
SLPEscape(const char * pcInbuf,char ** ppcOutBuf,SLPBoolean isTag)442*7c478bd9Sstevel@tonic-gate SLPError SLPEscape(const char *pcInbuf, char **ppcOutBuf, SLPBoolean isTag) {
443*7c478bd9Sstevel@tonic-gate char *buf, *pin, *pout;
444*7c478bd9Sstevel@tonic-gate
445*7c478bd9Sstevel@tonic-gate if (!pcInbuf || !ppcOutBuf)
446*7c478bd9Sstevel@tonic-gate return (SLP_PARAMETER_BAD);
447*7c478bd9Sstevel@tonic-gate
448*7c478bd9Sstevel@tonic-gate if (!(buf = malloc(strlen(pcInbuf) * 3 + 1))) {
449*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "SLPEscape", "out of memory");
450*7c478bd9Sstevel@tonic-gate return (SLP_MEMORY_ALLOC_FAILED);
451*7c478bd9Sstevel@tonic-gate }
452*7c478bd9Sstevel@tonic-gate *ppcOutBuf = buf;
453*7c478bd9Sstevel@tonic-gate
454*7c478bd9Sstevel@tonic-gate for (pin = (char *)pcInbuf, pout = buf; *pin; ) {
455*7c478bd9Sstevel@tonic-gate int len;
456*7c478bd9Sstevel@tonic-gate
457*7c478bd9Sstevel@tonic-gate /* If char is start of multibyte char, just copy it in */
458*7c478bd9Sstevel@tonic-gate if ((len = mblen(pin, MB_CUR_MAX)) > 1) {
459*7c478bd9Sstevel@tonic-gate int i;
460*7c478bd9Sstevel@tonic-gate for (i = 0; i < len && *pin; i++)
461*7c478bd9Sstevel@tonic-gate *pout++ = *pin++;
462*7c478bd9Sstevel@tonic-gate continue;
463*7c478bd9Sstevel@tonic-gate }
464*7c478bd9Sstevel@tonic-gate
465*7c478bd9Sstevel@tonic-gate /* check for bad tag */
466*7c478bd9Sstevel@tonic-gate if (isTag && isBadTagChar(*pin))
467*7c478bd9Sstevel@tonic-gate return (SLP_PARSE_ERROR);
468*7c478bd9Sstevel@tonic-gate
469*7c478bd9Sstevel@tonic-gate if (isReserved(*pin)) {
470*7c478bd9Sstevel@tonic-gate if (isTag)
471*7c478bd9Sstevel@tonic-gate return (SLP_PARSE_ERROR);
472*7c478bd9Sstevel@tonic-gate (void) sprintf(pout, "\\%.2x", *pin);
473*7c478bd9Sstevel@tonic-gate pout += 3;
474*7c478bd9Sstevel@tonic-gate pin++;
475*7c478bd9Sstevel@tonic-gate } else {
476*7c478bd9Sstevel@tonic-gate *pout++ = *pin++;
477*7c478bd9Sstevel@tonic-gate }
478*7c478bd9Sstevel@tonic-gate }
479*7c478bd9Sstevel@tonic-gate *pout = 0;
480*7c478bd9Sstevel@tonic-gate
481*7c478bd9Sstevel@tonic-gate return (SLP_OK);
482*7c478bd9Sstevel@tonic-gate }
483*7c478bd9Sstevel@tonic-gate
SLPUnescape(const char * pcInbuf,char ** ppcOutBuf,SLPBoolean isTag)484*7c478bd9Sstevel@tonic-gate SLPError SLPUnescape(const char *pcInbuf, char **ppcOutBuf, SLPBoolean isTag) {
485*7c478bd9Sstevel@tonic-gate if (!pcInbuf || !ppcOutBuf)
486*7c478bd9Sstevel@tonic-gate return (SLP_PARAMETER_BAD);
487*7c478bd9Sstevel@tonic-gate
488*7c478bd9Sstevel@tonic-gate return (slp_unescape(pcInbuf, ppcOutBuf, isTag, '\\'));
489*7c478bd9Sstevel@tonic-gate }
490*7c478bd9Sstevel@tonic-gate
491*7c478bd9Sstevel@tonic-gate
492*7c478bd9Sstevel@tonic-gate /*
493*7c478bd9Sstevel@tonic-gate * The actual unescaping routine; allows for different escape chars.
494*7c478bd9Sstevel@tonic-gate */
slp_unescape(const char * pcInbuf,char ** ppcOutBuf,SLPBoolean isTag,const char esc_char)495*7c478bd9Sstevel@tonic-gate static SLPError slp_unescape(const char *pcInbuf, char **ppcOutBuf,
496*7c478bd9Sstevel@tonic-gate SLPBoolean isTag, const char esc_char) {
497*7c478bd9Sstevel@tonic-gate char *buf, *pin, *pout, conv[3];
498*7c478bd9Sstevel@tonic-gate
499*7c478bd9Sstevel@tonic-gate if (!(buf = malloc(strlen(pcInbuf) * 3 + 1))) {
500*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "SLPEscape", "out of memory");
501*7c478bd9Sstevel@tonic-gate return (SLP_MEMORY_ALLOC_FAILED);
502*7c478bd9Sstevel@tonic-gate }
503*7c478bd9Sstevel@tonic-gate *ppcOutBuf = buf;
504*7c478bd9Sstevel@tonic-gate
505*7c478bd9Sstevel@tonic-gate conv[2] = 0;
506*7c478bd9Sstevel@tonic-gate for (pin = (char *)pcInbuf, pout = buf; *pin; ) {
507*7c478bd9Sstevel@tonic-gate int len;
508*7c478bd9Sstevel@tonic-gate
509*7c478bd9Sstevel@tonic-gate /* If char is start of multibyte char, just copy it in */
510*7c478bd9Sstevel@tonic-gate if ((len = mblen(pin, MB_CUR_MAX)) > 1) {
511*7c478bd9Sstevel@tonic-gate int i;
512*7c478bd9Sstevel@tonic-gate for (i = 0; i < len && *pin; i++)
513*7c478bd9Sstevel@tonic-gate *pout++ = *pin++;
514*7c478bd9Sstevel@tonic-gate continue;
515*7c478bd9Sstevel@tonic-gate }
516*7c478bd9Sstevel@tonic-gate
517*7c478bd9Sstevel@tonic-gate if (*pin == esc_char) {
518*7c478bd9Sstevel@tonic-gate if (!pin[1] || !pin[2])
519*7c478bd9Sstevel@tonic-gate return (SLP_PARSE_ERROR);
520*7c478bd9Sstevel@tonic-gate pin++;
521*7c478bd9Sstevel@tonic-gate conv[0] = *pin++;
522*7c478bd9Sstevel@tonic-gate conv[1] = *pin++;
523*7c478bd9Sstevel@tonic-gate *pout++ = (char)strtol(conv, NULL, 16);
524*7c478bd9Sstevel@tonic-gate if (isTag && isBadTagChar(*pout))
525*7c478bd9Sstevel@tonic-gate return (SLP_PARSE_ERROR);
526*7c478bd9Sstevel@tonic-gate } else {
527*7c478bd9Sstevel@tonic-gate *pout++ = *pin++;
528*7c478bd9Sstevel@tonic-gate }
529*7c478bd9Sstevel@tonic-gate }
530*7c478bd9Sstevel@tonic-gate *pout = 0;
531*7c478bd9Sstevel@tonic-gate
532*7c478bd9Sstevel@tonic-gate return (SLP_OK);
533*7c478bd9Sstevel@tonic-gate }
534*7c478bd9Sstevel@tonic-gate
535*7c478bd9Sstevel@tonic-gate /*
536*7c478bd9Sstevel@tonic-gate * Properties
537*7c478bd9Sstevel@tonic-gate *
538*7c478bd9Sstevel@tonic-gate * All properties are stored in a global tree (prop_table). This
539*7c478bd9Sstevel@tonic-gate * tree is created and accessed by slp_tsearch and slp_tfind.
540*7c478bd9Sstevel@tonic-gate */
541*7c478bd9Sstevel@tonic-gate struct prop_entry {
542*7c478bd9Sstevel@tonic-gate const char *key, *val;
543*7c478bd9Sstevel@tonic-gate };
544*7c478bd9Sstevel@tonic-gate typedef struct prop_entry slp_prop_entry_t;
545*7c478bd9Sstevel@tonic-gate
546*7c478bd9Sstevel@tonic-gate /* Global properties table */
547*7c478bd9Sstevel@tonic-gate static void *slp_props = NULL;
548*7c478bd9Sstevel@tonic-gate static mutex_t prop_table_lock = DEFAULTMUTEX;
549*7c478bd9Sstevel@tonic-gate
550*7c478bd9Sstevel@tonic-gate static void setDefaults();
551*7c478bd9Sstevel@tonic-gate
compare_props(const void * a,const void * b)552*7c478bd9Sstevel@tonic-gate static int compare_props(const void *a, const void *b) {
553*7c478bd9Sstevel@tonic-gate return (strcmp(
554*7c478bd9Sstevel@tonic-gate ((slp_prop_entry_t *)a)->key,
555*7c478bd9Sstevel@tonic-gate ((slp_prop_entry_t *)b)->key));
556*7c478bd9Sstevel@tonic-gate }
557*7c478bd9Sstevel@tonic-gate
SLPSetProperty(const char * pcName,const char * pcValue)558*7c478bd9Sstevel@tonic-gate void SLPSetProperty(const char *pcName, const char *pcValue) {
559*7c478bd9Sstevel@tonic-gate slp_prop_entry_t *pe, **pe2;
560*7c478bd9Sstevel@tonic-gate
561*7c478bd9Sstevel@tonic-gate if (!slp_props) setDefaults();
562*7c478bd9Sstevel@tonic-gate
563*7c478bd9Sstevel@tonic-gate if (!pcName || !pcValue) {
564*7c478bd9Sstevel@tonic-gate return;
565*7c478bd9Sstevel@tonic-gate }
566*7c478bd9Sstevel@tonic-gate
567*7c478bd9Sstevel@tonic-gate if (!(pe = malloc(sizeof (*pe)))) {
568*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "SLPSetProperty", "out of memory");
569*7c478bd9Sstevel@tonic-gate return;
570*7c478bd9Sstevel@tonic-gate }
571*7c478bd9Sstevel@tonic-gate
572*7c478bd9Sstevel@tonic-gate /* place the strings under library ownership */
573*7c478bd9Sstevel@tonic-gate if (!(pe->key = strdup(pcName))) {
574*7c478bd9Sstevel@tonic-gate free(pe);
575*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "SLPSetProperty", "out of memory");
576*7c478bd9Sstevel@tonic-gate return;
577*7c478bd9Sstevel@tonic-gate }
578*7c478bd9Sstevel@tonic-gate
579*7c478bd9Sstevel@tonic-gate if (!(pe->val = strdup(pcValue))) {
580*7c478bd9Sstevel@tonic-gate free((void *) pe->key);
581*7c478bd9Sstevel@tonic-gate free(pe);
582*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "SLPSetProperty", "out of memory");
583*7c478bd9Sstevel@tonic-gate return;
584*7c478bd9Sstevel@tonic-gate }
585*7c478bd9Sstevel@tonic-gate
586*7c478bd9Sstevel@tonic-gate /* is pcName already set? */
587*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&prop_table_lock);
588*7c478bd9Sstevel@tonic-gate pe2 = slp_tsearch((void *) pe, &slp_props, compare_props);
589*7c478bd9Sstevel@tonic-gate if (pe != *pe2) {
590*7c478bd9Sstevel@tonic-gate /* this prop is already set; overwrite the old value */
591*7c478bd9Sstevel@tonic-gate free((void *) (*pe2)->val);
592*7c478bd9Sstevel@tonic-gate (*pe2)->val = pe->val;
593*7c478bd9Sstevel@tonic-gate free((void *) pe->key);
594*7c478bd9Sstevel@tonic-gate free(pe);
595*7c478bd9Sstevel@tonic-gate }
596*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&prop_table_lock);
597*7c478bd9Sstevel@tonic-gate }
598*7c478bd9Sstevel@tonic-gate
SLPGetProperty(const char * pcName)599*7c478bd9Sstevel@tonic-gate const char *SLPGetProperty(const char *pcName) {
600*7c478bd9Sstevel@tonic-gate slp_prop_entry_t pe[1], **ans;
601*7c478bd9Sstevel@tonic-gate
602*7c478bd9Sstevel@tonic-gate if (!slp_props) setDefaults();
603*7c478bd9Sstevel@tonic-gate
604*7c478bd9Sstevel@tonic-gate if (!pcName) {
605*7c478bd9Sstevel@tonic-gate return (NULL);
606*7c478bd9Sstevel@tonic-gate }
607*7c478bd9Sstevel@tonic-gate
608*7c478bd9Sstevel@tonic-gate pe->key = pcName;
609*7c478bd9Sstevel@tonic-gate
610*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&prop_table_lock);
611*7c478bd9Sstevel@tonic-gate ans = slp_tfind(pe, &slp_props, compare_props);
612*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&prop_table_lock);
613*7c478bd9Sstevel@tonic-gate if (ans)
614*7c478bd9Sstevel@tonic-gate return ((*ans)->val);
615*7c478bd9Sstevel@tonic-gate return (NULL);
616*7c478bd9Sstevel@tonic-gate }
617*7c478bd9Sstevel@tonic-gate
setDefaults()618*7c478bd9Sstevel@tonic-gate static void setDefaults() {
619*7c478bd9Sstevel@tonic-gate slp_prop_entry_t *pe;
620*7c478bd9Sstevel@tonic-gate static mutex_t lock = DEFAULTMUTEX;
621*7c478bd9Sstevel@tonic-gate
622*7c478bd9Sstevel@tonic-gate (void) mutex_lock(&lock);
623*7c478bd9Sstevel@tonic-gate if (slp_props) {
624*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&lock);
625*7c478bd9Sstevel@tonic-gate return;
626*7c478bd9Sstevel@tonic-gate }
627*7c478bd9Sstevel@tonic-gate
628*7c478bd9Sstevel@tonic-gate pe = malloc(sizeof (*pe));
629*7c478bd9Sstevel@tonic-gate pe->key = strdup(SLP_CONFIG_ISBROADCASTONLY);
630*7c478bd9Sstevel@tonic-gate pe->val = strdup("false");
631*7c478bd9Sstevel@tonic-gate (void) slp_tsearch((void *) pe, &slp_props, compare_props);
632*7c478bd9Sstevel@tonic-gate
633*7c478bd9Sstevel@tonic-gate pe = malloc(sizeof (*pe));
634*7c478bd9Sstevel@tonic-gate pe->key = strdup(SLP_CONFIG_MULTICASTTTL);
635*7c478bd9Sstevel@tonic-gate pe->val = strdup("255");
636*7c478bd9Sstevel@tonic-gate (void) slp_tsearch((void *) pe, &slp_props, compare_props);
637*7c478bd9Sstevel@tonic-gate
638*7c478bd9Sstevel@tonic-gate pe = malloc(sizeof (*pe));
639*7c478bd9Sstevel@tonic-gate pe->key = strdup(SLP_CONFIG_MULTICASTMAXWAIT);
640*7c478bd9Sstevel@tonic-gate pe->val = strdup("15000");
641*7c478bd9Sstevel@tonic-gate (void) slp_tsearch((void *) pe, &slp_props, compare_props);
642*7c478bd9Sstevel@tonic-gate
643*7c478bd9Sstevel@tonic-gate pe = malloc(sizeof (*pe));
644*7c478bd9Sstevel@tonic-gate pe->key = strdup(SLP_CONFIG_DATAGRAMTIMEOUTS);
645*7c478bd9Sstevel@tonic-gate pe->val = strdup("2000,2000,2000");
646*7c478bd9Sstevel@tonic-gate (void) slp_tsearch((void *) pe, &slp_props, compare_props);
647*7c478bd9Sstevel@tonic-gate
648*7c478bd9Sstevel@tonic-gate pe = malloc(sizeof (*pe));
649*7c478bd9Sstevel@tonic-gate pe->key = strdup(SLP_CONFIG_MULTICASTTIMEOUTS);
650*7c478bd9Sstevel@tonic-gate pe->val = strdup("1000,3000,3000,3000,3000");
651*7c478bd9Sstevel@tonic-gate (void) slp_tsearch((void *) pe, &slp_props, compare_props);
652*7c478bd9Sstevel@tonic-gate
653*7c478bd9Sstevel@tonic-gate pe = malloc(sizeof (*pe));
654*7c478bd9Sstevel@tonic-gate pe->key = SLP_CONFIG_MTU; pe->val = "1400";
655*7c478bd9Sstevel@tonic-gate (void) slp_tsearch((void *) pe, &slp_props, compare_props);
656*7c478bd9Sstevel@tonic-gate
657*7c478bd9Sstevel@tonic-gate pe = malloc(sizeof (*pe));
658*7c478bd9Sstevel@tonic-gate pe->key = strdup(SLP_CONFIG_MAXRESULTS);
659*7c478bd9Sstevel@tonic-gate pe->val = strdup("-1");
660*7c478bd9Sstevel@tonic-gate (void) slp_tsearch((void *) pe, &slp_props, compare_props);
661*7c478bd9Sstevel@tonic-gate
662*7c478bd9Sstevel@tonic-gate pe = malloc(sizeof (*pe));
663*7c478bd9Sstevel@tonic-gate pe->key = strdup(SLP_CONFIG_SECURITY_ON);
664*7c478bd9Sstevel@tonic-gate pe->val = strdup("false");
665*7c478bd9Sstevel@tonic-gate (void) slp_tsearch((void *) pe, &slp_props, compare_props);
666*7c478bd9Sstevel@tonic-gate
667*7c478bd9Sstevel@tonic-gate pe = malloc(sizeof (*pe));
668*7c478bd9Sstevel@tonic-gate pe->key = strdup(SLP_CONFIG_BYPASS_AUTH);
669*7c478bd9Sstevel@tonic-gate pe->val = strdup("false");
670*7c478bd9Sstevel@tonic-gate (void) slp_tsearch((void *) pe, &slp_props, compare_props);
671*7c478bd9Sstevel@tonic-gate
672*7c478bd9Sstevel@tonic-gate slp_readConfig();
673*7c478bd9Sstevel@tonic-gate
674*7c478bd9Sstevel@tonic-gate (void) mutex_unlock(&lock);
675*7c478bd9Sstevel@tonic-gate }
676*7c478bd9Sstevel@tonic-gate
677*7c478bd9Sstevel@tonic-gate static const char *error_strings[] = {
678*7c478bd9Sstevel@tonic-gate "OK", /* 0 */
679*7c478bd9Sstevel@tonic-gate "Language not supported", /* -1 */
680*7c478bd9Sstevel@tonic-gate "Parse error", /* -2 */
681*7c478bd9Sstevel@tonic-gate "Invalid registration", /* -3 */
682*7c478bd9Sstevel@tonic-gate "Scope not supported", /* -4 */
683*7c478bd9Sstevel@tonic-gate "Invalid error number", /* -5 */
684*7c478bd9Sstevel@tonic-gate "Authentication absent", /* -6 */
685*7c478bd9Sstevel@tonic-gate "Authentication failed", /* -7 */
686*7c478bd9Sstevel@tonic-gate "Invalid error number", /* -8 */
687*7c478bd9Sstevel@tonic-gate "Invalid error number", /* -9 */
688*7c478bd9Sstevel@tonic-gate "Invalid error number", /* -10 */
689*7c478bd9Sstevel@tonic-gate "Invalid error number", /* -11 */
690*7c478bd9Sstevel@tonic-gate "Invalid error number", /* -12 */
691*7c478bd9Sstevel@tonic-gate "Invalid update", /* -13 */
692*7c478bd9Sstevel@tonic-gate "Invalid error number", /* -14 */
693*7c478bd9Sstevel@tonic-gate "Invalid error number", /* -15 */
694*7c478bd9Sstevel@tonic-gate "Invalid error number", /* -16 */
695*7c478bd9Sstevel@tonic-gate "Not implemented", /* -17 */
696*7c478bd9Sstevel@tonic-gate "Buffer overflow", /* -18 */
697*7c478bd9Sstevel@tonic-gate "Network timed out", /* -19 */
698*7c478bd9Sstevel@tonic-gate "Network init failed", /* -20 */
699*7c478bd9Sstevel@tonic-gate "Memory alloc failed", /* -21 */
700*7c478bd9Sstevel@tonic-gate "Parameter bad", /* -22 */
701*7c478bd9Sstevel@tonic-gate "Network error", /* -23 */
702*7c478bd9Sstevel@tonic-gate "Internal system error", /* -24 */
703*7c478bd9Sstevel@tonic-gate "Handle in use", /* -25 */
704*7c478bd9Sstevel@tonic-gate "Type error" /* -26 */
705*7c478bd9Sstevel@tonic-gate };
706*7c478bd9Sstevel@tonic-gate
707*7c478bd9Sstevel@tonic-gate #define SLP_MAX_ERR_CNT 26
708*7c478bd9Sstevel@tonic-gate
slp_strerror(SLPError err)709*7c478bd9Sstevel@tonic-gate const char *slp_strerror(SLPError err) {
710*7c478bd9Sstevel@tonic-gate int abserr;
711*7c478bd9Sstevel@tonic-gate const char *str;
712*7c478bd9Sstevel@tonic-gate
713*7c478bd9Sstevel@tonic-gate if (err == SLP_LAST_CALL) {
714*7c478bd9Sstevel@tonic-gate str = "Last call";
715*7c478bd9Sstevel@tonic-gate } else if (err == SLP_SECURITY_UNAVAILABLE) {
716*7c478bd9Sstevel@tonic-gate str = "Security Implementation Unavailable";
717*7c478bd9Sstevel@tonic-gate } else {
718*7c478bd9Sstevel@tonic-gate abserr = abs(err);
719*7c478bd9Sstevel@tonic-gate if (abserr > SLP_MAX_ERR_CNT) {
720*7c478bd9Sstevel@tonic-gate str = "Invalid error number";
721*7c478bd9Sstevel@tonic-gate } else {
722*7c478bd9Sstevel@tonic-gate str = error_strings[abserr];
723*7c478bd9Sstevel@tonic-gate }
724*7c478bd9Sstevel@tonic-gate }
725*7c478bd9Sstevel@tonic-gate
726*7c478bd9Sstevel@tonic-gate return (dgettext("libslp", str));
727*7c478bd9Sstevel@tonic-gate }
728