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 #include <stdio.h> 30*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 31*7c478bd9Sstevel@tonic-gate #include <syslog.h> 32*7c478bd9Sstevel@tonic-gate #include <slp-internal.h> 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate struct surl_node { 35*7c478bd9Sstevel@tonic-gate char *surl; 36*7c478bd9Sstevel@tonic-gate unsigned short lifetime; 37*7c478bd9Sstevel@tonic-gate }; 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate struct caller_bundle { 40*7c478bd9Sstevel@tonic-gate SLPSrvURLCallback *cb; 41*7c478bd9Sstevel@tonic-gate void *cookie; 42*7c478bd9Sstevel@tonic-gate SLPHandle handle; 43*7c478bd9Sstevel@tonic-gate }; 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate static int compare_surls(struct surl_node *, struct surl_node *); 46*7c478bd9Sstevel@tonic-gate static char *collate_surls(char *, unsigned short, void **); 47*7c478bd9Sstevel@tonic-gate static void traverse_surls(SLPHandle, SLPSrvURLCallback, void *, void *); 48*7c478bd9Sstevel@tonic-gate static void process_surl_node(void *, VISIT, int, void *); 49*7c478bd9Sstevel@tonic-gate static SLPBoolean unpackDAAdvert_srv(slp_handle_impl_t *, char *, 50*7c478bd9Sstevel@tonic-gate SLPSrvURLCallback, void *, 51*7c478bd9Sstevel@tonic-gate void **, int *); 52*7c478bd9Sstevel@tonic-gate static SLPBoolean unpackSAAdvert_srv(slp_handle_impl_t *, char *, 53*7c478bd9Sstevel@tonic-gate SLPSrvURLCallback, void *, 54*7c478bd9Sstevel@tonic-gate void **, int *); 55*7c478bd9Sstevel@tonic-gate 56*7c478bd9Sstevel@tonic-gate SLPError SLPFindSrvs(SLPHandle hSLP, const char *pcServiceType, 57*7c478bd9Sstevel@tonic-gate const char *pcScope, const char *pcSearchFilter, 58*7c478bd9Sstevel@tonic-gate SLPSrvURLCallback callback, void *pvUser) { 59*7c478bd9Sstevel@tonic-gate SLPError err; 60*7c478bd9Sstevel@tonic-gate slp_handle_impl_t *hp = (slp_handle_impl_t *)hSLP; 61*7c478bd9Sstevel@tonic-gate int wantSAAdvert = 62*7c478bd9Sstevel@tonic-gate strcasecmp(pcServiceType, "service:service-agent") == 0; 63*7c478bd9Sstevel@tonic-gate int wantDAAdvert = 64*7c478bd9Sstevel@tonic-gate strcasecmp(pcServiceType, "service:directory-agent") == 0; 65*7c478bd9Sstevel@tonic-gate int isSpecial = wantSAAdvert || wantDAAdvert; 66*7c478bd9Sstevel@tonic-gate SLPMsgReplyCB *unpack_cb; 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate if (!hSLP || !pcServiceType || !pcScope || (!*pcScope && !isSpecial) || 69*7c478bd9Sstevel@tonic-gate !pcSearchFilter || !callback) { 70*7c478bd9Sstevel@tonic-gate return (SLP_PARAMETER_BAD); 71*7c478bd9Sstevel@tonic-gate } 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate if ((strlen(pcServiceType) > SLP_MAX_STRINGLEN) || 74*7c478bd9Sstevel@tonic-gate (strlen(pcScope) > SLP_MAX_STRINGLEN) || 75*7c478bd9Sstevel@tonic-gate (strlen(pcSearchFilter) > SLP_MAX_STRINGLEN)) { 76*7c478bd9Sstevel@tonic-gate return (SLP_PARAMETER_BAD); 77*7c478bd9Sstevel@tonic-gate } 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate if ((err = slp_start_call(hSLP)) != SLP_OK) 80*7c478bd9Sstevel@tonic-gate return (err); 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate /* Special unpacker for DA and SA solicitations */ 83*7c478bd9Sstevel@tonic-gate if (wantDAAdvert) { 84*7c478bd9Sstevel@tonic-gate unpack_cb = (SLPMsgReplyCB *)unpackDAAdvert_srv; 85*7c478bd9Sstevel@tonic-gate hp->force_multicast = SLP_TRUE; 86*7c478bd9Sstevel@tonic-gate } else if (wantSAAdvert) { 87*7c478bd9Sstevel@tonic-gate unpack_cb = (SLPMsgReplyCB *)unpackSAAdvert_srv; 88*7c478bd9Sstevel@tonic-gate hp->force_multicast = SLP_TRUE; 89*7c478bd9Sstevel@tonic-gate } else { 90*7c478bd9Sstevel@tonic-gate /* normal service request */ 91*7c478bd9Sstevel@tonic-gate unpack_cb = (SLPMsgReplyCB *)slp_unpackSrvReply; 92*7c478bd9Sstevel@tonic-gate } 93*7c478bd9Sstevel@tonic-gate 94*7c478bd9Sstevel@tonic-gate err = slp_packSrvRqst(pcServiceType, pcSearchFilter, hp); 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate if (err == SLP_OK) 97*7c478bd9Sstevel@tonic-gate err = slp_ua_common(hSLP, pcScope, 98*7c478bd9Sstevel@tonic-gate (SLPGenericAppCB *) callback, pvUser, 99*7c478bd9Sstevel@tonic-gate unpack_cb); 100*7c478bd9Sstevel@tonic-gate if (err != SLP_OK) 101*7c478bd9Sstevel@tonic-gate slp_end_call(hSLP); 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate return (err); 104*7c478bd9Sstevel@tonic-gate } 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate SLPBoolean slp_unpackSrvReply(slp_handle_impl_t *hp, char *reply, 107*7c478bd9Sstevel@tonic-gate SLPSrvURLCallback cb, void *cookie, 108*7c478bd9Sstevel@tonic-gate void **collator, int *numResults) { 109*7c478bd9Sstevel@tonic-gate SLPError errCode; 110*7c478bd9Sstevel@tonic-gate unsigned short urlCount, protoErrCode; 111*7c478bd9Sstevel@tonic-gate size_t len, off; 112*7c478bd9Sstevel@tonic-gate int i; 113*7c478bd9Sstevel@tonic-gate int maxResults = slp_get_maxResults(); 114*7c478bd9Sstevel@tonic-gate SLPBoolean cont = SLP_TRUE; 115*7c478bd9Sstevel@tonic-gate 116*7c478bd9Sstevel@tonic-gate if (!reply) { 117*7c478bd9Sstevel@tonic-gate /* no more results */ 118*7c478bd9Sstevel@tonic-gate /* traverse_surls:invoke cb for sync case,and free resources */ 119*7c478bd9Sstevel@tonic-gate if (!hp->async) { 120*7c478bd9Sstevel@tonic-gate traverse_surls(hp, cb, cookie, *collator); 121*7c478bd9Sstevel@tonic-gate } 122*7c478bd9Sstevel@tonic-gate cb(hp, NULL, 0, SLP_LAST_CALL, cookie); 123*7c478bd9Sstevel@tonic-gate return (SLP_FALSE); 124*7c478bd9Sstevel@tonic-gate } 125*7c478bd9Sstevel@tonic-gate 126*7c478bd9Sstevel@tonic-gate len = slp_get_length(reply); 127*7c478bd9Sstevel@tonic-gate off = SLP_HDRLEN + slp_get_langlen(reply); 128*7c478bd9Sstevel@tonic-gate /* err code */ 129*7c478bd9Sstevel@tonic-gate if (slp_get_sht(reply, len, &off, &protoErrCode) != SLP_OK) 130*7c478bd9Sstevel@tonic-gate return (SLP_TRUE); 131*7c478bd9Sstevel@tonic-gate /* internal errors should have been filtered out by the net code */ 132*7c478bd9Sstevel@tonic-gate if ((errCode = slp_map_err(protoErrCode)) != SLP_OK) { 133*7c478bd9Sstevel@tonic-gate return (cb(hp, NULL, 0, errCode, cookie)); 134*7c478bd9Sstevel@tonic-gate } 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate /* url entry count */ 137*7c478bd9Sstevel@tonic-gate if (slp_get_sht(reply, len, &off, &urlCount) != SLP_OK) 138*7c478bd9Sstevel@tonic-gate return (SLP_TRUE); 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate /* for each srvRply, unpack and pass to CB */ 141*7c478bd9Sstevel@tonic-gate for (i = 0; i < urlCount && !hp->cancel; i++) { 142*7c478bd9Sstevel@tonic-gate char *pcSrvURL; 143*7c478bd9Sstevel@tonic-gate unsigned short sLifetime; 144*7c478bd9Sstevel@tonic-gate int nURLAuthBlocks; 145*7c478bd9Sstevel@tonic-gate size_t tbv_len; 146*7c478bd9Sstevel@tonic-gate char *url_tbv; 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate /* parse URL entry into params */ 149*7c478bd9Sstevel@tonic-gate off++; /* skip reserved byte */ 150*7c478bd9Sstevel@tonic-gate /* lifetime */ 151*7c478bd9Sstevel@tonic-gate if (slp_get_sht(reply, len, &off, &sLifetime) != SLP_OK) 152*7c478bd9Sstevel@tonic-gate return (SLP_TRUE); 153*7c478bd9Sstevel@tonic-gate /* URL itself; keep track of it in case we need to verify */ 154*7c478bd9Sstevel@tonic-gate url_tbv = reply + off; 155*7c478bd9Sstevel@tonic-gate tbv_len = off; 156*7c478bd9Sstevel@tonic-gate if (slp_get_string(reply, len, &off, &pcSrvURL) != SLP_OK) 157*7c478bd9Sstevel@tonic-gate return (SLP_TRUE); 158*7c478bd9Sstevel@tonic-gate tbv_len = off - tbv_len; 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate /* number of url auths */ 161*7c478bd9Sstevel@tonic-gate if (slp_get_byte(reply, len, &off, &nURLAuthBlocks) != SLP_OK) 162*7c478bd9Sstevel@tonic-gate goto cleanup; 163*7c478bd9Sstevel@tonic-gate 164*7c478bd9Sstevel@tonic-gate /* get and verify auth blocks */ 165*7c478bd9Sstevel@tonic-gate if ((!hp->internal_call && slp_get_security_on()) || 166*7c478bd9Sstevel@tonic-gate nURLAuthBlocks > 0) { 167*7c478bd9Sstevel@tonic-gate struct iovec iov[1]; 168*7c478bd9Sstevel@tonic-gate size_t abLen = 0; 169*7c478bd9Sstevel@tonic-gate 170*7c478bd9Sstevel@tonic-gate iov[0].iov_base = url_tbv; 171*7c478bd9Sstevel@tonic-gate iov[0].iov_len = tbv_len; 172*7c478bd9Sstevel@tonic-gate 173*7c478bd9Sstevel@tonic-gate if (slp_verify(iov, 1, 174*7c478bd9Sstevel@tonic-gate reply + off, 175*7c478bd9Sstevel@tonic-gate len - off, 176*7c478bd9Sstevel@tonic-gate nURLAuthBlocks, 177*7c478bd9Sstevel@tonic-gate &abLen) != SLP_OK) { 178*7c478bd9Sstevel@tonic-gate goto cleanup; 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate off += abLen; 181*7c478bd9Sstevel@tonic-gate } 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate /* collate the srv urls for sync behavior */ 184*7c478bd9Sstevel@tonic-gate if (!hp->async) { 185*7c478bd9Sstevel@tonic-gate pcSrvURL = collate_surls(pcSrvURL, sLifetime, collator); 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate if (!pcSrvURL) 188*7c478bd9Sstevel@tonic-gate continue; 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate (*numResults)++; 192*7c478bd9Sstevel@tonic-gate /* invoke cb */ 193*7c478bd9Sstevel@tonic-gate if (hp->async) 194*7c478bd9Sstevel@tonic-gate cont = cb( 195*7c478bd9Sstevel@tonic-gate (SLPHandle) hp, 196*7c478bd9Sstevel@tonic-gate pcSrvURL, 197*7c478bd9Sstevel@tonic-gate sLifetime, 198*7c478bd9Sstevel@tonic-gate errCode, 199*7c478bd9Sstevel@tonic-gate cookie); 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate /* cleanup */ 202*7c478bd9Sstevel@tonic-gate cleanup: 203*7c478bd9Sstevel@tonic-gate free(pcSrvURL); 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate /* check maxResults */ 206*7c478bd9Sstevel@tonic-gate if (!hp->internal_call && *numResults == maxResults) { 207*7c478bd9Sstevel@tonic-gate cont = SLP_FALSE; 208*7c478bd9Sstevel@tonic-gate } 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate if (!cont) break; 211*7c478bd9Sstevel@tonic-gate } 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate return (cont); 214*7c478bd9Sstevel@tonic-gate } 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate /* 217*7c478bd9Sstevel@tonic-gate * unpackDAAdvert_srv follows the same same logic flow as slp_unpackSrvReply 218*7c478bd9Sstevel@tonic-gate * with two differences: the message in reply is a DAAdvert, and 219*7c478bd9Sstevel@tonic-gate * this function is not used internally, so hp is never NULL. Although 220*7c478bd9Sstevel@tonic-gate * all info from a DAAdvert is returned by slp_unpackDAAdvert, here 221*7c478bd9Sstevel@tonic-gate * the recipient (the user-supplied SLPSrvURLCallback) is interested 222*7c478bd9Sstevel@tonic-gate * only in the DA service URL. 223*7c478bd9Sstevel@tonic-gate */ 224*7c478bd9Sstevel@tonic-gate static SLPBoolean unpackDAAdvert_srv(slp_handle_impl_t *hp, char *reply, 225*7c478bd9Sstevel@tonic-gate SLPSrvURLCallback cb, void *cookie, 226*7c478bd9Sstevel@tonic-gate void **collator, int *numResults) { 227*7c478bd9Sstevel@tonic-gate char *surl, *scopes, *attrs, *spis; 228*7c478bd9Sstevel@tonic-gate SLPBoolean cont = SLP_TRUE; 229*7c478bd9Sstevel@tonic-gate SLPError errCode; 230*7c478bd9Sstevel@tonic-gate int maxResults = slp_get_maxResults(); 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate if (!reply) { 233*7c478bd9Sstevel@tonic-gate /* no more results */ 234*7c478bd9Sstevel@tonic-gate /* traverse_surls:invoke cb for sync case,and free resources */ 235*7c478bd9Sstevel@tonic-gate if (!hp->async) { 236*7c478bd9Sstevel@tonic-gate traverse_surls(hp, cb, cookie, *collator); 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate cb(hp, NULL, 0, SLP_LAST_CALL, cookie); 239*7c478bd9Sstevel@tonic-gate return (SLP_FALSE); 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate if (slp_unpackDAAdvert(reply, &surl, &scopes, &attrs, &spis, &errCode) 243*7c478bd9Sstevel@tonic-gate != SLP_OK) { 244*7c478bd9Sstevel@tonic-gate return (SLP_TRUE); 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate if (errCode != SLP_OK) { 247*7c478bd9Sstevel@tonic-gate return (cb(hp, NULL, 0, errCode, cookie)); 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate 250*7c478bd9Sstevel@tonic-gate /* collate the urls */ 251*7c478bd9Sstevel@tonic-gate surl = collate_surls(surl, 0, collator); 252*7c478bd9Sstevel@tonic-gate if (!surl) { 253*7c478bd9Sstevel@tonic-gate return (SLP_TRUE); 254*7c478bd9Sstevel@tonic-gate } 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate (*numResults)++; 257*7c478bd9Sstevel@tonic-gate if (hp->async) { 258*7c478bd9Sstevel@tonic-gate cont = cb((SLPHandle)hp, surl, 0, errCode, cookie); 259*7c478bd9Sstevel@tonic-gate } 260*7c478bd9Sstevel@tonic-gate 261*7c478bd9Sstevel@tonic-gate /* cleanup */ 262*7c478bd9Sstevel@tonic-gate free(surl); 263*7c478bd9Sstevel@tonic-gate free(scopes); 264*7c478bd9Sstevel@tonic-gate free(attrs); 265*7c478bd9Sstevel@tonic-gate free(spis); 266*7c478bd9Sstevel@tonic-gate 267*7c478bd9Sstevel@tonic-gate /* check maxResults */ 268*7c478bd9Sstevel@tonic-gate if (!hp->internal_call && *numResults == maxResults) { 269*7c478bd9Sstevel@tonic-gate return (SLP_FALSE); 270*7c478bd9Sstevel@tonic-gate } 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate return (cont); 273*7c478bd9Sstevel@tonic-gate } 274*7c478bd9Sstevel@tonic-gate /* 275*7c478bd9Sstevel@tonic-gate * unpackSAAdvert_srv follows the same same logic flow as slp_unpackSrvReply 276*7c478bd9Sstevel@tonic-gate * with two differences: the message in reply is a SAAdvert, and 277*7c478bd9Sstevel@tonic-gate * this function is not used internally, so hp is never NULL. Although 278*7c478bd9Sstevel@tonic-gate * all info from an SAAdvert is returned by slp_unpackSAAdvert, here 279*7c478bd9Sstevel@tonic-gate * the recipient (the user-supplied SLPSrvURLCallback) is interested 280*7c478bd9Sstevel@tonic-gate * only in the SA service URL. 281*7c478bd9Sstevel@tonic-gate */ 282*7c478bd9Sstevel@tonic-gate static SLPBoolean unpackSAAdvert_srv(slp_handle_impl_t *hp, char *reply, 283*7c478bd9Sstevel@tonic-gate SLPSrvURLCallback cb, void *cookie, 284*7c478bd9Sstevel@tonic-gate void **collator, int *numResults) { 285*7c478bd9Sstevel@tonic-gate char *surl, *scopes, *attrs; 286*7c478bd9Sstevel@tonic-gate SLPBoolean cont = SLP_TRUE; 287*7c478bd9Sstevel@tonic-gate int maxResults = slp_get_maxResults(); 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate if (!reply) { 290*7c478bd9Sstevel@tonic-gate /* no more results */ 291*7c478bd9Sstevel@tonic-gate /* traverse_surls:invoke cb for sync case,and free resources */ 292*7c478bd9Sstevel@tonic-gate if (!hp->async) { 293*7c478bd9Sstevel@tonic-gate /* sync case */ 294*7c478bd9Sstevel@tonic-gate traverse_surls(hp, cb, cookie, *collator); 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate cb(hp, NULL, 0, SLP_LAST_CALL, cookie); 297*7c478bd9Sstevel@tonic-gate return (SLP_FALSE); 298*7c478bd9Sstevel@tonic-gate } 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate if (slp_unpackSAAdvert(reply, &surl, &scopes, &attrs) != SLP_OK) { 301*7c478bd9Sstevel@tonic-gate return (SLP_TRUE); 302*7c478bd9Sstevel@tonic-gate } 303*7c478bd9Sstevel@tonic-gate 304*7c478bd9Sstevel@tonic-gate /* collate the urls */ 305*7c478bd9Sstevel@tonic-gate surl = collate_surls(surl, 0, collator); 306*7c478bd9Sstevel@tonic-gate if (!surl) { 307*7c478bd9Sstevel@tonic-gate return (SLP_TRUE); 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate 310*7c478bd9Sstevel@tonic-gate (*numResults)++; 311*7c478bd9Sstevel@tonic-gate if (hp->async) { 312*7c478bd9Sstevel@tonic-gate cont = cb((SLPHandle)hp, surl, 0, SLP_OK, cookie); 313*7c478bd9Sstevel@tonic-gate } 314*7c478bd9Sstevel@tonic-gate 315*7c478bd9Sstevel@tonic-gate /* cleanup */ 316*7c478bd9Sstevel@tonic-gate free(surl); 317*7c478bd9Sstevel@tonic-gate free(scopes); 318*7c478bd9Sstevel@tonic-gate free(attrs); 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate /* check maxResults */ 321*7c478bd9Sstevel@tonic-gate if (!hp->internal_call && *numResults == maxResults) { 322*7c478bd9Sstevel@tonic-gate return (SLP_FALSE); 323*7c478bd9Sstevel@tonic-gate } 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate return (cont); 326*7c478bd9Sstevel@tonic-gate } 327*7c478bd9Sstevel@tonic-gate 328*7c478bd9Sstevel@tonic-gate SLPError slp_packSrvRqst(const char *type, 329*7c478bd9Sstevel@tonic-gate const char *filter, 330*7c478bd9Sstevel@tonic-gate slp_handle_impl_t *hp) { 331*7c478bd9Sstevel@tonic-gate SLPError err; 332*7c478bd9Sstevel@tonic-gate size_t len, msgLen, tmplen; 333*7c478bd9Sstevel@tonic-gate slp_msg_t *msg = &(hp->msg); 334*7c478bd9Sstevel@tonic-gate char *spi = NULL; 335*7c478bd9Sstevel@tonic-gate 336*7c478bd9Sstevel@tonic-gate if (slp_get_security_on()) { 337*7c478bd9Sstevel@tonic-gate spi = (char *)SLPGetProperty(SLP_CONFIG_SPI); 338*7c478bd9Sstevel@tonic-gate } 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate if (!spi || !*spi) { 341*7c478bd9Sstevel@tonic-gate spi = ""; 342*7c478bd9Sstevel@tonic-gate } 343*7c478bd9Sstevel@tonic-gate 344*7c478bd9Sstevel@tonic-gate /* 345*7c478bd9Sstevel@tonic-gate * Allocate iovec for the messge. A SrvRqst is layed out thus: 346*7c478bd9Sstevel@tonic-gate * 0: header 347*7c478bd9Sstevel@tonic-gate * 1: prlist length 348*7c478bd9Sstevel@tonic-gate * 2: prlist (filled in later by networking code) 349*7c478bd9Sstevel@tonic-gate * 3: service type string 350*7c478bd9Sstevel@tonic-gate * 4: scopes length 351*7c478bd9Sstevel@tonic-gate * 5: scopes (filled in later by networking code) 352*7c478bd9Sstevel@tonic-gate * 6: predicate string and SPI string 353*7c478bd9Sstevel@tonic-gate */ 354*7c478bd9Sstevel@tonic-gate if (!(msg->iov = calloc(7, sizeof (*(msg->iov))))) { 355*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "slp_packSrvRqst", "out of memory"); 356*7c478bd9Sstevel@tonic-gate return (SLP_MEMORY_ALLOC_FAILED); 357*7c478bd9Sstevel@tonic-gate } 358*7c478bd9Sstevel@tonic-gate msg->iovlen = 7; 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate /* calculate msg length */ 361*7c478bd9Sstevel@tonic-gate msgLen = 2 + /* prlist length */ 362*7c478bd9Sstevel@tonic-gate 2 + strlen(type) + /* service type */ 363*7c478bd9Sstevel@tonic-gate 2 + /* scope list length */ 364*7c478bd9Sstevel@tonic-gate 2 + strlen(filter) + /* predicate string */ 365*7c478bd9Sstevel@tonic-gate 2 + strlen(spi); /* SPI string */ 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate if (!(msg->msg = calloc(1, msgLen))) { 368*7c478bd9Sstevel@tonic-gate free(msg->iov); 369*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "slp_packSrvRqst", "out of memory"); 370*7c478bd9Sstevel@tonic-gate return (SLP_MEMORY_ALLOC_FAILED); 371*7c478bd9Sstevel@tonic-gate } 372*7c478bd9Sstevel@tonic-gate 373*7c478bd9Sstevel@tonic-gate /* set pointer to PR list and scope list length spaces */ 374*7c478bd9Sstevel@tonic-gate msg->prlistlen.iov_base = msg->msg; 375*7c478bd9Sstevel@tonic-gate msg->prlistlen.iov_len = 2; 376*7c478bd9Sstevel@tonic-gate msg->iov[1].iov_base = msg->msg; 377*7c478bd9Sstevel@tonic-gate msg->iov[1].iov_len = 2; 378*7c478bd9Sstevel@tonic-gate 379*7c478bd9Sstevel@tonic-gate msg->scopeslen.iov_base = msg->msg + 2; 380*7c478bd9Sstevel@tonic-gate msg->scopeslen.iov_len = 2; 381*7c478bd9Sstevel@tonic-gate msg->iov[4].iov_base = msg->msg + 2; 382*7c478bd9Sstevel@tonic-gate msg->iov[4].iov_len = 2; 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate /* set up the scopes and prlist pointers into iov */ 385*7c478bd9Sstevel@tonic-gate msg->prlist = &(msg->iov[2]); 386*7c478bd9Sstevel@tonic-gate msg->scopes = &(msg->iov[5]); 387*7c478bd9Sstevel@tonic-gate 388*7c478bd9Sstevel@tonic-gate len = 4; 389*7c478bd9Sstevel@tonic-gate 390*7c478bd9Sstevel@tonic-gate /* Add type string */ 391*7c478bd9Sstevel@tonic-gate msg->iov[3].iov_base = msg->msg + len; 392*7c478bd9Sstevel@tonic-gate tmplen = len; 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate err = slp_add_string(msg->msg, msgLen, type, &len); 395*7c478bd9Sstevel@tonic-gate msg->iov[3].iov_len = len - tmplen; 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate if (err != SLP_OK) 398*7c478bd9Sstevel@tonic-gate goto error; 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate /* Add search filter */ 401*7c478bd9Sstevel@tonic-gate msg->iov[6].iov_base = msg->msg + len; 402*7c478bd9Sstevel@tonic-gate tmplen = len; 403*7c478bd9Sstevel@tonic-gate 404*7c478bd9Sstevel@tonic-gate err = slp_add_string(msg->msg, msgLen, filter, &len); 405*7c478bd9Sstevel@tonic-gate if (err != SLP_OK) 406*7c478bd9Sstevel@tonic-gate goto error; 407*7c478bd9Sstevel@tonic-gate 408*7c478bd9Sstevel@tonic-gate err = slp_add_string(msg->msg, msgLen, spi, &len); 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate msg->iov[6].iov_len = len - tmplen; 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate hp->fid = SRVRQST; 413*7c478bd9Sstevel@tonic-gate 414*7c478bd9Sstevel@tonic-gate if (err == SLP_OK) { 415*7c478bd9Sstevel@tonic-gate return (err); 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate /* else error */ 419*7c478bd9Sstevel@tonic-gate error: 420*7c478bd9Sstevel@tonic-gate free(msg->iov); 421*7c478bd9Sstevel@tonic-gate free(msg->msg); 422*7c478bd9Sstevel@tonic-gate 423*7c478bd9Sstevel@tonic-gate return (err); 424*7c478bd9Sstevel@tonic-gate } 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate /* 427*7c478bd9Sstevel@tonic-gate * Caller must free msg 428*7c478bd9Sstevel@tonic-gate */ 429*7c478bd9Sstevel@tonic-gate SLPError slp_packSrvRqst_single(const char *type, 430*7c478bd9Sstevel@tonic-gate const char *scopes, 431*7c478bd9Sstevel@tonic-gate const char *filter, 432*7c478bd9Sstevel@tonic-gate char **msg, 433*7c478bd9Sstevel@tonic-gate const char *lang) { 434*7c478bd9Sstevel@tonic-gate SLPError err; 435*7c478bd9Sstevel@tonic-gate size_t len, msgLen; 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate msgLen = 438*7c478bd9Sstevel@tonic-gate SLP_HDRLEN + strlen(lang) + 2 + 439*7c478bd9Sstevel@tonic-gate 2 + strlen(type) + 440*7c478bd9Sstevel@tonic-gate 2 + strlen(scopes) + 441*7c478bd9Sstevel@tonic-gate 2 + strlen(filter) + 442*7c478bd9Sstevel@tonic-gate 2; /* No SPI string for internal calls */ 443*7c478bd9Sstevel@tonic-gate 444*7c478bd9Sstevel@tonic-gate if (!(*msg = calloc(msgLen, 1))) { 445*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "slp_packSrvRqst_single", 446*7c478bd9Sstevel@tonic-gate "out of memory"); 447*7c478bd9Sstevel@tonic-gate return (SLP_MEMORY_ALLOC_FAILED); 448*7c478bd9Sstevel@tonic-gate } 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate len = 0; 451*7c478bd9Sstevel@tonic-gate err = slp_add_header(lang, *msg, msgLen, SRVRQST, msgLen, &len); 452*7c478bd9Sstevel@tonic-gate 453*7c478bd9Sstevel@tonic-gate len += 2; /* empty PR list */ 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate if (err == SLP_OK) 456*7c478bd9Sstevel@tonic-gate err = slp_add_string(*msg, msgLen, type, &len); 457*7c478bd9Sstevel@tonic-gate if (err == SLP_OK) 458*7c478bd9Sstevel@tonic-gate err = slp_add_string(*msg, msgLen, scopes, &len); 459*7c478bd9Sstevel@tonic-gate if (err == SLP_OK) 460*7c478bd9Sstevel@tonic-gate err = slp_add_string(*msg, msgLen, filter, &len); 461*7c478bd9Sstevel@tonic-gate if (err == SLP_OK) 462*7c478bd9Sstevel@tonic-gate /* empty SPI string */ 463*7c478bd9Sstevel@tonic-gate err = slp_add_string(*msg, msgLen, "", &len); 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate return (err); 466*7c478bd9Sstevel@tonic-gate } 467*7c478bd9Sstevel@tonic-gate 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate static int compare_surls(struct surl_node *s1, struct surl_node *s2) { 470*7c478bd9Sstevel@tonic-gate if (s1->lifetime != s2->lifetime) 471*7c478bd9Sstevel@tonic-gate return (s1->lifetime - s2->lifetime); 472*7c478bd9Sstevel@tonic-gate return (slp_strcasecmp(s1->surl, s2->surl)); 473*7c478bd9Sstevel@tonic-gate } 474*7c478bd9Sstevel@tonic-gate 475*7c478bd9Sstevel@tonic-gate /* 476*7c478bd9Sstevel@tonic-gate * Using the collator, determine if this URL has already been processed. 477*7c478bd9Sstevel@tonic-gate * If so, free surl and return NULL, else return the URL. 478*7c478bd9Sstevel@tonic-gate */ 479*7c478bd9Sstevel@tonic-gate static char *collate_surls(char *surl, unsigned short life, void **collator) { 480*7c478bd9Sstevel@tonic-gate struct surl_node *n, **res; 481*7c478bd9Sstevel@tonic-gate 482*7c478bd9Sstevel@tonic-gate if (!(n = malloc(sizeof (*n)))) { 483*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "collate_surls", "out of memory"); 484*7c478bd9Sstevel@tonic-gate return (NULL); 485*7c478bd9Sstevel@tonic-gate } 486*7c478bd9Sstevel@tonic-gate if (!(n->surl = strdup(surl))) { 487*7c478bd9Sstevel@tonic-gate free(n); 488*7c478bd9Sstevel@tonic-gate slp_err(LOG_CRIT, 0, "collate_surls", "out of memory"); 489*7c478bd9Sstevel@tonic-gate return (NULL); 490*7c478bd9Sstevel@tonic-gate } 491*7c478bd9Sstevel@tonic-gate n->lifetime = life; 492*7c478bd9Sstevel@tonic-gate res = slp_tsearch((void *) n, collator, 493*7c478bd9Sstevel@tonic-gate (int (*)(const void *, const void *)) compare_surls); 494*7c478bd9Sstevel@tonic-gate if (*res == n) { 495*7c478bd9Sstevel@tonic-gate /* first time we've encountered this url */ 496*7c478bd9Sstevel@tonic-gate return (surl); 497*7c478bd9Sstevel@tonic-gate } 498*7c478bd9Sstevel@tonic-gate /* else already in tree */ 499*7c478bd9Sstevel@tonic-gate free(n->surl); 500*7c478bd9Sstevel@tonic-gate free(n); 501*7c478bd9Sstevel@tonic-gate free(surl); 502*7c478bd9Sstevel@tonic-gate return (NULL); 503*7c478bd9Sstevel@tonic-gate } 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate static void traverse_surls(SLPHandle h, SLPSrvURLCallback cb, 506*7c478bd9Sstevel@tonic-gate void *cookie, void *collator) { 507*7c478bd9Sstevel@tonic-gate struct caller_bundle caller[1]; 508*7c478bd9Sstevel@tonic-gate 509*7c478bd9Sstevel@tonic-gate if (!collator) 510*7c478bd9Sstevel@tonic-gate return; 511*7c478bd9Sstevel@tonic-gate caller->cb = cb; 512*7c478bd9Sstevel@tonic-gate caller->cookie = cookie; 513*7c478bd9Sstevel@tonic-gate caller->handle = h; 514*7c478bd9Sstevel@tonic-gate slp_twalk(collator, process_surl_node, 0, caller); 515*7c478bd9Sstevel@tonic-gate } 516*7c478bd9Sstevel@tonic-gate 517*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 518*7c478bd9Sstevel@tonic-gate static void process_surl_node(void *node, VISIT order, int level, void *c) { 519*7c478bd9Sstevel@tonic-gate struct surl_node *n; 520*7c478bd9Sstevel@tonic-gate SLPSrvURLCallback *cb; 521*7c478bd9Sstevel@tonic-gate slp_handle_impl_t *h; 522*7c478bd9Sstevel@tonic-gate struct caller_bundle *caller = (struct caller_bundle *)c; 523*7c478bd9Sstevel@tonic-gate 524*7c478bd9Sstevel@tonic-gate if (order == endorder || order == leaf) { 525*7c478bd9Sstevel@tonic-gate SLPBoolean cont = SLP_TRUE; 526*7c478bd9Sstevel@tonic-gate 527*7c478bd9Sstevel@tonic-gate cb = caller->cb; 528*7c478bd9Sstevel@tonic-gate h = (slp_handle_impl_t *)caller->handle; 529*7c478bd9Sstevel@tonic-gate n = *(struct surl_node **)node; 530*7c478bd9Sstevel@tonic-gate /* invoke cb */ 531*7c478bd9Sstevel@tonic-gate if (cont && (!h || !h->async)) 532*7c478bd9Sstevel@tonic-gate cont = cb( 533*7c478bd9Sstevel@tonic-gate h, n->surl, 534*7c478bd9Sstevel@tonic-gate n->lifetime, 535*7c478bd9Sstevel@tonic-gate SLP_OK, 536*7c478bd9Sstevel@tonic-gate caller->cookie); 537*7c478bd9Sstevel@tonic-gate 538*7c478bd9Sstevel@tonic-gate free(n->surl); 539*7c478bd9Sstevel@tonic-gate free(n); 540*7c478bd9Sstevel@tonic-gate free(node); 541*7c478bd9Sstevel@tonic-gate } 542*7c478bd9Sstevel@tonic-gate } 543