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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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*/ 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*/ 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 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 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 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 */ 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 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 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 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 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 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