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