1 /*-------------------------------------------------------------------------
2 * Copyright (C) 2000 Caldera Systems, Inc
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * Neither the name of Caldera Systems nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA
24 * SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
28 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *-------------------------------------------------------------------------*/
32
33 /** OpenSLP command line User Agent wrapper.
34 *
35 * This file contains code that provide command line access to all OpenSLP
36 * User Agent library functionality.
37 *
38 * @file slptool.c
39 * @author Matthew Peterson, John Calcote (jcalcote@novell.com)
40 * @attention Please submit patches to http://www.openslp.org
41 * @ingroup SlpToolCode
42 */
43
44 #include "slptool.h"
45
46 #ifndef _WIN32
47 # ifndef HAVE_STRCASECMP
strncasecmp(const char * s1,const char * s2,size_t len)48 static int strncasecmp(const char * s1, const char * s2, size_t len)
49 {
50 while (len && *s1 && *s2 && ((*s1 ^ *s2) & ~0x20) == 0)
51 len--, s1++, s2++;
52 return len? (int)(*(unsigned char *)s1 - *(unsigned char *)s2): 0;
53 }
strcasecmp(const char * s1,const char * s2)54 static int strcasecmp(const char * s1, const char * s2)
55 {
56 while (*s1 && *s2 && ((*s1 ^ *s2) & ~0x20) == 0)
57 s1++, s2++;
58 return (int)(*(unsigned char *)s1 - *(unsigned char *)s2);
59 }
60 # endif
61 #endif
62
mySrvTypeCallback(SLPHandle hslp,const char * srvtypes,SLPError errcode,void * cookie)63 static SLPBoolean mySrvTypeCallback(SLPHandle hslp,
64 const char * srvtypes, SLPError errcode, void * cookie)
65 {
66 char * cpy;
67 char * slider1;
68 char * slider2;
69
70 (void)hslp;
71 (void)cookie;
72
73 if (errcode == SLP_OK && *srvtypes)
74 {
75 cpy = strdup(srvtypes);
76 if (cpy)
77 {
78 slider1 = slider2 = cpy;
79 slider1 = strchr(slider2, ',');
80 while (slider1)
81 {
82 *slider1 = 0;
83 printf("%s\n", slider2);
84 slider1 ++;
85 slider2 = slider1;
86 slider1 = strchr(slider2, ',');
87 }
88
89 /* print the final itam */
90 printf("%s\n", slider2);
91
92 free(cpy);
93 }
94 }
95 return SLP_TRUE;
96 }
97
FindSrvTypes(SLPToolCommandLine * cmdline)98 void FindSrvTypes(SLPToolCommandLine * cmdline)
99 {
100 SLPError result;
101 SLPHandle hslp;
102
103 if (SLPOpen(cmdline->lang, SLP_FALSE, &hslp) == SLP_OK)
104 {
105 #ifndef UNICAST_NOT_SUPPORTED
106 if (cmdline->unicastifc && (result = SLPAssociateIP(hslp,
107 cmdline->unicastifc)) != SLP_OK)
108 {
109 printf("errorcode: %i\n", result);
110 SLPClose(hslp);
111 return;
112 }
113 #endif
114 #ifndef MI_NOT_SUPPORTED
115 if (cmdline->interfaces && (result = SLPAssociateIFList(hslp,
116 cmdline->interfaces)) != SLP_OK)
117 {
118 printf("errorcode: %i\n", result);
119 SLPClose(hslp);
120 return;
121 }
122
123 #endif
124 if (cmdline->cmdparam1)
125 result = SLPFindSrvTypes(hslp, cmdline->cmdparam1, cmdline->scopes,
126 mySrvTypeCallback, 0);
127 else
128 result = SLPFindSrvTypes(hslp, "*", cmdline->scopes,
129 mySrvTypeCallback, 0);
130
131 if (result != SLP_OK)
132 printf("errorcode: %i\n", result);
133
134 SLPClose(hslp);
135 }
136 }
137
myAttrCallback(SLPHandle hslp,const char * attrlist,SLPError errcode,void * cookie)138 static SLPBoolean myAttrCallback(SLPHandle hslp,
139 const char * attrlist, SLPError errcode, void * cookie)
140 {
141 (void)hslp;
142 (void)cookie;
143
144 if (errcode == SLP_OK)
145 printf("%s\n", attrlist);
146
147 return SLP_TRUE;
148 }
149
FindAttrs(SLPToolCommandLine * cmdline)150 void FindAttrs(SLPToolCommandLine * cmdline)
151 {
152 SLPError result;
153 SLPHandle hslp;
154
155 if (SLPOpen(cmdline->lang, SLP_FALSE, &hslp) == SLP_OK)
156 {
157 #ifndef UNICAST_NOT_SUPPORTED
158 if (cmdline->unicastifc && (result = SLPAssociateIP(hslp,
159 cmdline->unicastifc)) != SLP_OK)
160 {
161 printf("errorcode: %i\n", result);
162 SLPClose(hslp);
163 return;
164 }
165 #endif
166 #ifndef MI_NOT_SUPPORTED
167 if (cmdline->interfaces && (result = SLPAssociateIFList(hslp,
168 cmdline->interfaces)) != SLP_OK)
169 {
170 printf("errorcode: %i\n", result);
171 SLPClose(hslp);
172 return;
173 }
174 #endif
175 result = SLPFindAttrs(hslp, cmdline->cmdparam1, cmdline->scopes,
176 cmdline->cmdparam2, myAttrCallback, 0);
177 if (result != SLP_OK)
178 printf("errorcode: %i\n", result);
179 SLPClose(hslp);
180 }
181 }
182
mySrvUrlCallback(SLPHandle hslp,const char * srvurl,unsigned short lifetime,SLPError errcode,void * cookie)183 static SLPBoolean mySrvUrlCallback(SLPHandle hslp, const char * srvurl,
184 unsigned short lifetime, SLPError errcode, void * cookie)
185 {
186 (void)hslp;
187 (void)cookie;
188
189 if (errcode == SLP_OK)
190 printf("%s,%i\n", srvurl, lifetime);
191
192 return SLP_TRUE;
193 }
194
FindSrvs(SLPToolCommandLine * cmdline)195 void FindSrvs(SLPToolCommandLine * cmdline)
196 {
197 SLPError result;
198 SLPHandle hslp;
199
200 if (SLPOpen(cmdline->lang, SLP_FALSE, &hslp) == SLP_OK)
201 {
202 #ifndef UNICAST_NOT_SUPPORTED
203 if (cmdline->unicastifc && (result = SLPAssociateIP(hslp,
204 cmdline->unicastifc)) != SLP_OK)
205 {
206 printf("errorcode: %i\n", result);
207 SLPClose(hslp);
208 return;
209 }
210 #endif
211 #ifndef MI_NOT_SUPPORTED
212 if (cmdline->interfaces && (result = SLPAssociateIFList(hslp,
213 cmdline->interfaces)) != SLP_OK)
214 {
215 printf("errorcode: %i\n", result);
216 SLPClose(hslp);
217 return;
218 }
219 #endif
220 result = SLPFindSrvs(hslp, cmdline->cmdparam1, cmdline->scopes,
221 cmdline->cmdparam2, mySrvUrlCallback, 0);
222 if (result != SLP_OK)
223 printf("errorcode: %i\n", result);
224 SLPClose(hslp);
225 }
226 }
227
FindScopes(SLPToolCommandLine * cmdline)228 void FindScopes(SLPToolCommandLine * cmdline)
229 {
230 SLPError result;
231 SLPHandle hslp;
232 char * scopes;
233
234 if (SLPOpen(cmdline->lang, SLP_FALSE, &hslp) == SLP_OK)
235 {
236 result = SLPFindScopes(hslp, &scopes);
237 if (result == SLP_OK)
238 {
239 printf("%s\n", scopes);
240 SLPFree(scopes);
241 }
242
243 SLPClose(hslp);
244 }
245 }
246
mySLPRegReport(SLPHandle hslp,SLPError errcode,void * cookie)247 static void mySLPRegReport(SLPHandle hslp, SLPError errcode,
248 void * cookie)
249 {
250 (void)hslp;
251 (void)cookie;
252
253 if (errcode)
254 printf("(de)registration errorcode %d\n", errcode);
255 }
256
Register(SLPToolCommandLine * cmdline)257 void Register(SLPToolCommandLine * cmdline)
258 {
259 SLPError result;
260 SLPHandle hslp;
261 char srvtype[80] = "", * s;
262 size_t len = 0;
263 unsigned int lt = 0;
264
265 if (cmdline->time) {
266 lt = atoi(cmdline->time);
267 }
268
269 if (strncasecmp(cmdline->cmdparam1, "service:", 8) == 0)
270 len = 8;
271
272 s = strchr(cmdline->cmdparam1 + len, ':');
273 if (!s)
274 {
275 printf("Invalid URL: %s\n", cmdline->cmdparam1);
276 return;
277 }
278 len = s - cmdline->cmdparam1;
279 strncpy(srvtype, cmdline->cmdparam1, len);
280 srvtype[len] = 0;
281
282 /* Clear property (if set), otherwise the register function is quite useless */
283 SLPSetProperty("net.slp.watchRegistrationPID", 0);
284
285 if ((cmdline->scopes != 0) && (*cmdline->scopes != 0))
286 SLPSetProperty("net.slp.useScopes", cmdline->scopes);
287
288 if (SLPOpen(cmdline->lang, SLP_FALSE, &hslp) == SLP_OK)
289 {
290 if (!lt || lt > SLP_LIFETIME_MAXIMUM)
291 result = SLPReg(hslp, cmdline->cmdparam1, SLP_LIFETIME_MAXIMUM, srvtype,
292 cmdline->cmdparam2, SLP_TRUE, mySLPRegReport, 0);
293 else
294 result = SLPReg(hslp, cmdline->cmdparam1, (unsigned short)lt, srvtype,
295 cmdline->cmdparam2, SLP_TRUE, mySLPRegReport, 0);
296 if (result != SLP_OK)
297 printf("errorcode: %i\n", result);
298 SLPClose(hslp);
299 }
300 }
301
Deregister(SLPToolCommandLine * cmdline)302 void Deregister(SLPToolCommandLine * cmdline)
303 {
304 SLPError result;
305 SLPHandle hslp;
306
307 if (SLPOpen(cmdline->lang, SLP_FALSE, &hslp) == SLP_OK)
308 {
309 result = SLPDereg(hslp, cmdline->cmdparam1, mySLPRegReport, 0);
310 if (result != SLP_OK)
311 printf("errorcode: %i\n", result);
312 SLPClose(hslp);
313 }
314 }
315
PrintVersion(SLPToolCommandLine * cmdline)316 void PrintVersion(SLPToolCommandLine * cmdline)
317 {
318 (void)cmdline;
319
320 printf("slptool version = %s\n", SLP_VERSION);
321 printf("libslp version = %s\n", SLPGetProperty("net.slp.OpenSLPVersion"));
322
323 printf("libslp configuration file = %s\n",
324 SLPGetProperty("net.slp.OpenSLPConfigFile"));
325 }
326
GetProperty(SLPToolCommandLine * cmdline)327 void GetProperty(SLPToolCommandLine * cmdline)
328 {
329 const char * propertyValue;
330
331 propertyValue = SLPGetProperty(cmdline->cmdparam1);
332 printf("%s = %s\n", cmdline->cmdparam1,
333 propertyValue == 0 ? "" : propertyValue);
334 }
335
336 /* Returns Zero on success. Non-zero on error. */
ParseCommandLine(int argc,char * argv[],SLPToolCommandLine * cmdline)337 int ParseCommandLine(int argc, char * argv[], SLPToolCommandLine * cmdline)
338 {
339 int i;
340
341 if (argc < 2)
342 return 1; /* not enough arguments */
343
344 for (i = 1; i < argc; i++)
345 {
346 if (strcasecmp(argv[i], "-v") == 0
347 || strcasecmp(argv[i], "--version") == 0)
348 {
349 if (i < argc)
350 {
351 cmdline->cmd = PRINT_VERSION;
352 return 0;
353 }
354 else
355 return 1;
356 }
357 else if (strcasecmp(argv[i], "-s") == 0
358 || strcasecmp(argv[i], "--scopes") == 0)
359 {
360 i++;
361 if (i < argc)
362 cmdline->scopes = argv[i];
363 else
364 return 1;
365 }
366 else if (strcasecmp(argv[i], "-l") == 0
367 || strcasecmp(argv[i], "--language") == 0)
368 {
369 i++;
370 if (i < argc)
371 cmdline->lang = argv[i];
372 else
373 return 1;
374 }
375 else if (strcasecmp(argv[i], "-t") == 0
376 || strcasecmp(argv[i], "--time") == 0)
377 {
378 i++;
379 if (i < argc)
380 cmdline->time = argv[i];
381 else
382 return 1;
383 }
384 #ifndef MI_NOT_SUPPORTED
385 else if (strcasecmp(argv[i], "-i") == 0
386 || strcasecmp(argv[i], "--interfaces") == 0)
387 {
388 if (cmdline->unicastifc != 0)
389 {
390 printf("slptool: Can't use -i and -u together.\n");
391 return -1;
392 }
393 i++;
394 if (i < argc)
395 cmdline->interfaces = argv[i];
396 else
397 return 1;
398 }
399 #endif
400 #ifndef UNICAST_NOT_SUPPORTED
401 else if (strcasecmp(argv[i], "-u") == 0
402 || strcasecmp(argv[i], "--unicastifc") == 0)
403 {
404 if (cmdline->interfaces != 0)
405 {
406 printf("slptool: Can't use -i and -u together.\n");
407 return -1;
408 }
409 i++;
410 if (i < argc)
411 cmdline->unicastifc = argv[i];
412 else
413 return 1;
414 }
415 #endif
416 else if (strcasecmp(argv[i], "findsrvs") == 0)
417 {
418 cmdline->cmd = FINDSRVS;
419
420 /* service type */
421 i++;
422 if (i < argc)
423 cmdline->cmdparam1 = argv[i];
424 else
425 return 1;
426
427 /* (optional) filter */
428 i++;
429 if (i < argc)
430 cmdline->cmdparam2 = argv[i];
431
432 break;
433 }
434 else if (strcasecmp(argv[i], "findattrs") == 0)
435 {
436 cmdline->cmd = FINDATTRS;
437
438 /* url or service type */
439 i++;
440 if (i < argc)
441 cmdline->cmdparam1 = argv[i];
442 else
443 return 1;
444
445 /* (optional) attrids */
446 i++;
447 if (i < argc)
448 cmdline->cmdparam2 = argv[i];
449 }
450 else if (strcasecmp(argv[i], "findsrvtypes") == 0)
451 {
452 cmdline->cmd = FINDSRVTYPES;
453
454 /* (optional) naming authority */
455 i++;
456 if (i < argc)
457 cmdline->cmdparam1 = argv[i];
458 }
459 else if (strcasecmp(argv[i], "findscopes") == 0)
460 cmdline->cmd = FINDSCOPES;
461 else if (strcasecmp(argv[i], "register") == 0)
462 {
463 cmdline->cmd = REGISTER;
464
465 /* url */
466 i++;
467 if (i < argc)
468 cmdline->cmdparam1 = argv[i];
469 else
470 return 1;
471
472 /* Optional attrids */
473 i++;
474 if (i < argc)
475 cmdline->cmdparam2 = argv[i];
476 else
477 cmdline->cmdparam2 = cmdline->cmdparam1
478 + strlen(cmdline->cmdparam1);
479
480 break;
481 }
482 else if (strcasecmp(argv[i], "deregister") == 0)
483 {
484 cmdline->cmd = DEREGISTER;
485
486 /* url */
487 i++;
488 if (i < argc)
489 cmdline->cmdparam1 = argv[i];
490 else
491 return 1;
492 }
493 else if (strcasecmp(argv[i], "getproperty") == 0)
494 {
495 cmdline->cmd = GETPROPERTY;
496 i++;
497 if (i < argc)
498 cmdline->cmdparam1 = argv[i];
499 else
500 return 1;
501 }
502 else
503 return 1;
504 }
505 return 0;
506 }
507
DisplayUsage()508 void DisplayUsage()
509 {
510 printf("Usage: slptool [options] command-and-arguments \n");
511 printf(" options may be:\n");
512 printf(" -v (or --version) displays the versions of slptool and OpenSLP.\n");
513 printf(" -s (or --scope) followed by a comma-separated list of scopes.\n");
514 printf(" -l (or --language) followed by a language tag.\n");
515 printf(" -t (or --time) followed by a lifetime tag.\n");
516 #ifndef MI_NOT_SUPPORTED
517 printf(" -i (or --interfaces) followed by a comma-separated list of interfaces.\n");
518 #endif /* MI_NOT_SUPPORTED */
519 #ifndef UNICAST_NOT_SUPPORTED
520 printf(" -u (or --unicastifc) followed by a single interface.\n");
521 #endif
522 printf("\n");
523 printf(" command-and-arguments may be:\n");
524 printf(" findsrvs service-type [filter]\n");
525 printf(" findattrs url [attrids]\n");
526 printf(" findsrvtypes [authority]\n");
527 printf(" findscopes\n");
528 printf(" register url [attrs]\n");
529 printf(" deregister url\n");
530 printf(" getproperty propertyname\n");
531 printf("\n");
532 printf("Examples:\n");
533 printf(" slptool register service:myserv.x://myhost.com \"(attr1=val1),(attr2=val2)\"\n");
534 printf(" slptool findsrvs service:myserv.x\n");
535 printf(" slptool findsrvs service:myserv.x \"(attr1=val1)\"\n");
536 #ifndef MI_NOT_SUPPORTED
537 printf(" slptool -i 10.77.13.240,192.168.250.240 findsrvs service:myserv.x\n");
538 #endif /* MI_NOT_SUPPORTED */
539 #ifndef UNICAST_NOT_SUPPORTED
540 printf(" slptool -u 10.77.13.237 findsrvs service:myserv.x \"(attr1=val1)\"\n");
541 #endif
542 printf(" slptool findattrs service:myserv.x://myhost.com\n");
543 printf(" slptool findattrs service:myserv.x://myhost.com attr1\n");
544 #ifndef MI_NOT_SUPPORTED
545 printf(" slptool -i 10.77.13.243 findattrs service:myserv.x://myhost.com attr1\n");
546 #endif /* MI_NOT_SUPPORTED */
547 #ifndef UNICAST_NOT_SUPPORTED
548 printf(" slptool -u 10.77.13.237 findattrs service:myserv.x://myhost.com attr1 \n");
549 #endif
550 printf(" slptool deregister service:myserv.x://myhost.com\n");
551 printf(" slptool getproperty net.slp.useScopes\n");
552 }
553
main(int argc,char * argv[])554 int main(int argc, char * argv[])
555 {
556 int result = 0;
557 SLPToolCommandLine cmdline;
558
559 /* zero out the cmdline */
560 memset(&cmdline, 0, sizeof(cmdline));
561
562 /* Parse the command line */
563 if (ParseCommandLine(argc, argv, &cmdline) == 0)
564 switch (cmdline.cmd)
565 {
566 case FINDSRVS:
567 FindSrvs(&cmdline);
568 break;
569
570 case FINDATTRS:
571 FindAttrs(&cmdline);
572 break;
573
574 case FINDSRVTYPES:
575 FindSrvTypes(&cmdline);
576 break;
577
578 case FINDSCOPES:
579 FindScopes(&cmdline);
580 break;
581
582 case GETPROPERTY:
583 GetProperty(&cmdline);
584 break;
585
586 case REGISTER:
587 Register(&cmdline);
588 break;
589
590 case DEREGISTER:
591 Deregister(&cmdline);
592 break;
593
594 case PRINT_VERSION:
595 PrintVersion(&cmdline);
596 break;
597
598 case DUMMY:
599 break;
600 }
601 else
602 {
603 DisplayUsage();
604 result = 1;
605 }
606
607 return result;
608 }
609
610 /*=========================================================================*/
611