1 martin 1.9 //%LICENSE////////////////////////////////////////////////////////////////
2 //
3 // Licensed to The Open Group (TOG) under one or more contributor license
4 // agreements. Refer to the OpenPegasusNOTICE.txt file distributed with
5 // this work for additional information regarding copyright ownership.
6 // Each contributor licenses this file to you under the OpenPegasus Open
7 // Source License; you may not use this file except in compliance with the
8 // License.
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a
11 // copy of this software and associated documentation files (the "Software"),
12 // to deal in the Software without restriction, including without limitation
13 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
14 // and/or sell copies of the Software, and to permit persons to whom the
15 // Software is furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included
18 // in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 martin 1.9 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
24 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
27 tony 1.1 //
|
28 martin 1.9 //////////////////////////////////////////////////////////////////////////
|
29 tony 1.1 //
30 //%/////////////////////////////////////////////////////////////////////////////
31
32 #include "OpenSLPWrapper.h"
|
33 tony 1.3 #include <ctype.h>
|
34 tony 1.1
35 PEGASUS_NAMESPACE_BEGIN
36
|
37 tony 1.3 // preprocessAttrList basically strips and folds the whitespace in the supplied
38 // list. It overwrites the existing list with its output as it goes.
39 //
40 // (The output will always be equal or shorter to the original in length).
41 //
42 // The input string is of the form:
|
43 kumpf 1.8 // [WS]Tag[WS] and
44 // [WS]([WS]Tag[WS]=[WS]Attr[EWS]Val[WS],[WS]val2[WS])[WS]
|
45 tony 1.3 // The input string consists of a 1 or more instances of the above strings
46 // in a comma separated list.
47 // [WS] = WhiteSpace and is deleted
48 // [EWS] = Embedded WhiteSpace and will be folded to a single space.
49
|
50 kumpf 1.8 static void preprocessAttrList(char* list)
|
51 tony 1.3 {
|
52 kumpf 1.8 bool eatWhiteSpace = false;
53 char* ptr = list;
54 char* wptr = list;
55 char last;
56
57 while (*ptr != '\0')
58 {
59 // Outer switch case deals with everything outsde of brackets ( )
60 switch(*ptr)
61 {
62 // We delete all whitespace outside of ( )
63 case ' ':
64 case '\t':
65 last = ' ';
66 break;
67
68 case '(':
69 // Start of a ( ) section
70 last = '(';
71 *wptr++ = *ptr;
72 // Process everything until closing )
73 kumpf 1.8 while (*++ptr != '\0' && *ptr != ')')
74 {
75 switch(*ptr)
76 {
77 case ' ':
78 case '\t':
79 // if we're deleting WS
80 if (eatWhiteSpace == true)
81 {
82 last = ' ';
83 break;
84 }
85 // if we're folding WS
86 if (last == ' ')
87 {
88 break;
89 }
90 last = ' ';
91 *wptr++ = ' ';
92 break;
93
94 kumpf 1.8 case ',':
95 case '=':
96 // delete any preceding WS.
97 // It will have been folded to a
98 // single space
99 if (last == ' ')
100 {
101 wptr--;
102 }
103 *wptr++ = *ptr;
104 last = *ptr;
105 // flag to delete any following WS
106 eatWhiteSpace = true;
107 break;
108
109 default:
110 // tag or attribute character
111 // flag to fold embedded WS
112 eatWhiteSpace = false;
113 last = *ptr;
114 *wptr++ = *ptr;
115 kumpf 1.8 }
116 }
117
118 // delete any WS before the closing )
119 if (*ptr == ')' && last == ' ')
120 {
121 wptr--;
122 }
123
124 // we're outside the ( ), so flag to delete WS
125 eatWhiteSpace = true;
126 *wptr++ = *ptr;
127 break;
128
129 default:
130 // Not WS, not inside ( ), so just copy it
131 *wptr++ = *ptr;
132 }
133 ptr++;
134 }
135 // Make sure "new" string is properly terminated.
136 kumpf 1.8 *wptr = '\0';
|
137 tony 1.3 }
138
139 // Assumes a list that has already been whitespace stripped/folded
140 // Overwrites input string with output.
141
|
142 kumpf 1.8 static void preprocessAttrValList(char* list)
|
143 tony 1.3 {
|
144 kumpf 1.8 char* wptr = list;
145 char* ptr = list;
146 char last = '\0';
147 bool opaque = false;
148
149 while (*ptr != '\0')
150 {
151 if (opaque == true)
152 {
153 *wptr++ = *ptr++;
154 continue;
155 }
|
156 tony 1.3 #ifdef STRIP_QUOTES
|
157 kumpf 1.8 if (*ptr == '"')
158 {
159 ptr++;
160 continue;
161 }
|
162 tony 1.3 #endif
163
|
164 kumpf 1.8 // Escape character or opaque sequence
165 if (*ptr == '\\')
166 {
167 if (*(ptr+1) != '\0' && *(ptr+2) != '\0')
168 {
169 if (*(ptr+1) == 'F' && *(ptr+2) == 'F')
170 {
171 opaque = true;
172 *wptr++ = *ptr++;
173 }
174 else
175 {
176 // Allow any character to be escaped
177 // rfc2608 says to only escape
178 // reserved characters
179 //
180 Uint8 n = *++ptr;
181 if (isdigit(*ptr))
182 n = (*ptr - '0');
183 else if (isupper(*ptr))
184 n = (*ptr - 'A' + 10);
185 kumpf 1.8 else
186 n = (*ptr - 'a' + 10);
187 *wptr = ((n & 0xf) << 4);
188
189 // Do second nibble
190 n = *++ptr;
191 if (isdigit(*ptr))
192 n = (*ptr - '0');
193 else if (isupper(*ptr))
194 n = (*ptr - 'A' + 10);
195 else
196 n = (*ptr - 'a' + 10);
197 *wptr += (n & 0xf);
198 wptr++;
199 ptr++;
200 continue;
201 }
202 }
203 }
204 // nothing special, just copy it
205 *wptr++ = *ptr++;
206 kumpf 1.8 }
207 *wptr = '\0';
|
208 tony 1.3 }
209
|
210 kumpf 1.8 static SLPBoolean wbemSrvUrlCallback(
211 SLPHandle hslp,
212 const char* srvurl,
213 unsigned short lifetime,
214 SLPError errcode,
215 void* cookie)
|
216 tony 1.1 {
|
217 kumpf 1.8 if (errcode == SLP_OK)
|
218 tony 1.1 {
|
219 kumpf 1.8 Array<String> *url_cookie = static_cast<Array<String> *>(cookie);
220 url_cookie->append(srvurl);
|
221 tony 1.1 }
|
222 kumpf 1.8
|
223 tony 1.1 return SLP_TRUE;
224 }
225
|
226 kumpf 1.8 static SLPBoolean wbemAttrCallback(
227 SLPHandle hslp,
228 const char* attrlist,
229 SLPError errcode,
230 void* cookie)
|
231 tony 1.1 {
|
232 kumpf 1.8 if (errcode == SLP_OK)
233 {
234 Array<Attribute> *attr_cookie = static_cast<Array<Attribute> *>(cookie);
235
236 // Allocate memory to hold working copy of list
237 char *list = new char[strlen(attrlist) + 1];
238
239 if (list == (char *)NULL)
240 {
241 // Ignore out of memory, just go.
242 return SLP_TRUE;
243 }
244
245 strcpy (list, attrlist);
246
247 // Remove/fold whitespace
248 preprocessAttrList(list);
249
250 char *end = list + strlen(list);
251 char *ptr = list;
252 char *nptr;
253 kumpf 1.8
254 while (ptr <= end)
255 {
256 if (*ptr == '(')
257 {
258 ptr++;
259 nptr = ptr;
260 while (nptr <= end && *nptr != '=')
261 {
262 nptr++;
263 }
264 *nptr = '\0';
265 preprocessAttrValList(ptr);
266 Attribute newAttr(ptr);
267 ptr = nptr+1;
268 while (nptr <= end)
269 {
270 if (*nptr == ',' || *nptr == ')')
271 {
272 bool isBracket = false;
273 if (*nptr == ')')
274 kumpf 1.8 {
275 isBracket = true;
276 }
277 *nptr = '\0';
278 preprocessAttrValList(ptr);
279 newAttr.addValue(ptr);
280 ptr = nptr + 1;
281 if (isBracket)
282 {
283 break;
284 }
285 }
286 else
287 {
288 nptr++;
289 }
290 }
291 attr_cookie->append(newAttr);
292 }
293
294 if (*ptr == ',')
295 kumpf 1.8 {
296 ptr++;
297 continue;
298 }
299
300 nptr = ptr;
301 while (nptr <= end && *nptr != ',')
302 {
303 nptr++;
304 }
305 *nptr = '\0';
306 attr_cookie->append(Attribute(ptr));
307 ptr = nptr+1;
308 continue;
309 }
310 delete [] list;
311 }
312 return SLP_TRUE;
|
313 tony 1.1 }
314
315 CIMServerDiscoveryRep::CIMServerDiscoveryRep()
316 {
317 }
318
319 CIMServerDiscoveryRep::~CIMServerDiscoveryRep()
320 {
321 }
322
|
323 kumpf 1.8 Array<CIMServerDescription> CIMServerDiscoveryRep::lookup(
324 const Array<Attribute>& criteria,
325 const SLPClientOptions* options)
|
326 tony 1.1 {
|
327 kumpf 1.8 SLPError result;
328 SLPHandle hslp;
329 Array<CIMServerDescription> connections;
330
331 // SLPOpen()
332 // @param1 - language - NULL is the default locale
333 // @param2 - async - FALSE is synchronous slp handle
334 // @param3 - handle - pointer to slp handle
335 if (SLPOpen(NULL, SLP_FALSE, &hslp) == SLP_OK)
|
336 tony 1.1 {
|
337 kumpf 1.8 Attribute attrServiceId;
338 for (Uint32 idx=0; idx<criteria.size(); idx++)
|
339 tony 1.1 {
|
340 kumpf 1.8 if (criteria[idx].getTag() == PEG_WBEM_SLP_SERVICE_ID)
|
341 tony 1.1 {
|
342 kumpf 1.8 attrServiceId = criteria[idx];
|
343 tony 1.1 }
344 }
345
|
346 kumpf 1.8 String serviceType(PEG_WBEM_SLP_TYPE);
347 Array <String> serviceAttrList = attrServiceId.getValues();
|
348 tony 1.3
|
349 kumpf 1.8 if (serviceAttrList.size() != 0 && serviceAttrList[0] != String::EMPTY)
350 {
351 serviceType = serviceAttrList[0];
352 }
353
354 // SLPFindSrvs()
355 // @param1 - handle - slp handle
356 // @param2 - service type - wbem
357 // @param3 - scope list - NULL is all localhost can query
358 // @param4 - filter - NULL is all that match type
359 // @param5 - pointer to custom data to use in callback
360 Array<String> urls;
361 result = SLPFindSrvs(
362 hslp,
363 (const char *)serviceType.getCString(),
364 NULL,
365 NULL,
366 wbemSrvUrlCallback,
367 (void *)&urls);
|
368 tony 1.1
|
369 kumpf 1.8 if (result == SLP_OK)
|
370 tony 1.1 {
|
371 kumpf 1.8 for (Uint32 i=0; i<urls.size(); i++)
|
372 tony 1.1 {
|
373 kumpf 1.8 CIMServerDescription connection(urls[i]);
|
374 tony 1.1
|
375 kumpf 1.8 Array<Attribute> attributes;
|
376 tony 1.1
|
377 kumpf 1.8 // SLPFindAttrs()
378 // @param1 - handle - slp handle
379 // @param2 - service url or type
380 // @param3 - scope list - NULL is all localhost can query
381 // @param4 - attribute list - NULL is all attributes
382 // @param5 - pointer to custom data to use in callback
383 result = SLPFindAttrs(
384 hslp,
385 (const char *)urls[i].getCString(),
386 NULL,
387 NULL,
388 wbemAttrCallback,
389 (void *)&attributes);
390
391 // SLPParseSrvURL()
392 // @param1 - url - obtained from SLPFindSrvs()
393 // @param2 - parsed url - output param
394 SLPSrvURL *pSrvUrl = NULL;
395 if (SLP_OK == SLPParseSrvURL(
396 (char *)((const char *)urls[i].getCString()),
397 &pSrvUrl))
|
398 tony 1.1 {
|
399 kumpf 1.8 // add to the end to protect against existing attributes
400 // of the same name.
401 Attribute tmpAttr(PEG_CUSTOM_ATTR_HOST);
402 tmpAttr.addValue(pSrvUrl->s_pcHost);
403 attributes.append(tmpAttr);
404
405 Attribute tmpAttr2(PEG_CUSTOM_ATTR_PORT);
406 CIMValue value(Uint32(pSrvUrl->s_iPort));
407 tmpAttr2.addValue(value.toString());
408 attributes.append(tmpAttr2);
|
409 tony 1.1
|
410 kumpf 1.8 // free up slp library memory
411 SLPFree(pSrvUrl);
|
412 tony 1.1 }
|
413 kumpf 1.8 connection.setAttributes(attributes);
414 connections.append(connection);
|
415 tony 1.1 }
416 }
417
|
418 kumpf 1.8 // SLPClose()
419 // @param1 - handle - slp handle
420 SLPClose(hslp);
|
421 tony 1.1 }
422
|
423 kumpf 1.8 return connections;
|
424 tony 1.1 }
425
426 PEGASUS_NAMESPACE_END
|