(file) Return to slp.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / slp

   1 mday  1.1 //%/////////////////////////////////////////////////////////////////////////////
   2           //
   3 kumpf 1.13 // Copyright (c) 2000, 2001, 2002 BMC Software, Hewlett-Packard Company, IBM,
   4            // The Open Group, Tivoli Systems
   5 mday  1.1  //
   6 kumpf 1.13 // Permission is hereby granted, free of charge, to any person obtaining a copy
   7            // of this software and associated documentation files (the "Software"), to
   8            // deal in the Software without restriction, including without limitation the
   9            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  10            // sell copies of the Software, and to permit persons to whom the Software is
  11            // furnished to do so, subject to the following conditions:
  12            // 
  13            // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
  14            // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
  15            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
  16            // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  17            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  18            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  19            // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  20            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21 mday  1.1  //
  22            //==============================================================================
  23            //
  24            // Author: Mike Day (mdday@us.ibm.com)
  25 ramnath 1.11 // 
  26              // Modified by:
  27              //         Ramnath Ravindran (Ramnath.Ravindran@compaq.com)
  28 mday    1.1  //
  29              //%/////////////////////////////////////////////////////////////////////////////
  30              
  31 kumpf   1.12 #include <Pegasus/Common/PegasusVersion.h>
  32 mike    1.5  #include "slp.h"
  33              
  34              #ifdef PEGASUS_OS_TRU64
  35              # include <unistd.h>
  36 ramnath 1.11 //extern "C" void usleep(unsigned int);
  37 mike    1.5  #endif
  38 mday    1.1  
  39 mike    1.6  #if defined(PEGASUS_OS_HPUX)
  40              # include <netdb.h>
  41              #endif
  42 mday    1.1  
  43 keith.petley 1.17 #if defined(PEGASUS_PLATFORM_SOLARIS_SPARC_CC)
  44                   # include <sys/sockio.h>
  45                   #endif
  46                   
  47 mday         1.1  PEGASUS_USING_STD;
  48                   
  49                   PEGASUS_NAMESPACE_BEGIN
  50                   
  51 mike         1.6  // This is necessary to avoid the "reinterpret cast" warning generated
  52                   // by the HP C++ compiler.
  53                   #define SOCKADDR_IN_CAST (struct sockaddr_in*)(void*)
  54                   #define SOCKADDR_CAST (struct sockaddr*)(void*)
  55                   
  56 mday         1.2  PEGASUS_EXPORT String slp_get_host_name(void)
  57 mday         1.1  {
  58 mday         1.2  
  59                     String s = String();
  60                     Sint8 *buf = new Sint8[255];
  61                     if( 0 == gethostname(buf, 254) ) 
  62 kumpf        1.16     s.append(buf);
  63 mday         1.2    delete buf;
  64                     return(s);
  65 mday         1.1  }
  66                   
  67                   
  68                   #ifdef _WIN32
  69                   PEGASUS_EXPORT int gethostbyname_r(const char *name, 
  70                   		    struct hostent *resultbuf, 
  71                   		    char *buf, 
  72                   		    size_t bufsize, 
  73                   		    struct hostent **result, 
  74                   		    int *errnop) 
  75                   {
  76                     name = name;
  77                     resultbuf = resultbuf;
  78                     buf = buf;
  79                     bufsize = bufsize;
  80                     
  81                     if(NULL == (*result = gethostbyname(name))) {
  82                       *errnop = WSAGetLastError();
  83                       return(-1);
  84                     } 
  85                     return(0);
  86 mday         1.1  }
  87                   
  88                   #endif
  89 chuck        1.14 #if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_TRU64) || defined(PEGASUS_OS_AIX) || defined(PEGASUS_OS_OS400)
  90 karl         1.3  
  91                   PEGASUS_EXPORT int gethostbyname_r(const char *name, 
  92                   		    struct hostent *resultbuf, 
  93                   		    char *buf, 
  94                   		    size_t bufsize, 
  95                   		    struct hostent **result, 
  96                   		    int *errnop) 
  97                   {
  98                     name = name;
  99                     resultbuf = resultbuf;
 100                     buf = buf;
 101                     bufsize = bufsize;
 102 chuck        1.15 
 103                   #ifndef PEGASUS_OS_OS400   
 104 karl         1.3    if(NULL == (*result = gethostbyname(name))) {
 105 chuck        1.15 #else
 106                     if(NULL == (*result = gethostbyname((char *)name))) {
 107                   #endif
 108 karl         1.3      *errnop = h_errno;
 109                       return(-1);
 110                     } 
 111                     return(0);
 112                   }
 113 mike         1.5  
 114 karl         1.3  #endif
 115 keith.petley 1.17 #ifdef PEGASUS_OS_SOLARIS
 116                   #define gethostbyname_r(name, resultbuf, buf, bufsize, result, errnop) \
 117                       (*result=gethostbyname_r(name, resultbuf, buf, bufsize, errnop),\
 118                       *errnop = *errnop)
 119                   
 120                   #endif
 121 karl         1.3  
 122 mday         1.4  PEGASUS_EXPORT void slp_get_addr_string_from_url(const Sint8 *url, String &addr) 
 123 mday         1.1  {
 124 mday         1.4    Sint8 *name = NULL;
 125                     struct sockaddr_in a;
 126                     if( get_addr_from_url( url, &a, NULL) ) {
 127                       name = new Sint8 [ 255 ] ;
 128 mday         1.1  #ifdef _WIN32
 129 mday         1.4      _snprintf(name, 254, "%s:%d", inet_ntoa(a.sin_addr), ntohs(a.sin_port) );
 130 mday         1.1  #else
 131 mike         1.5  
 132                   // ATTN: Mike Brasher: Hack to get built of TRU64:
 133                   #ifdef PEGASUS_OS_TRU64
 134                       sprintf(name, "%s:%d", inet_ntoa(a.sin_addr), ntohs(a.sin_port) );
 135                   #else
 136 mday         1.4      snprintf(name, 254, "%s:%d", inet_ntoa(a.sin_addr), ntohs(a.sin_port) );
 137 mday         1.1  #endif
 138 mike         1.5  
 139                   #endif
 140 mday         1.4      addr.clear();
 141                       addr = name;
 142 mday         1.2      delete [] name;
 143 mday         1.1    }
 144 mday         1.4    return ;
 145                   }
 146                   
 147                   PEGASUS_EXPORT void slp_get_host_string_from_url(const Sint8 *url, String &host) 
 148                   {
 149                     Sint8 *s;
 150                     struct sockaddr_in addr;
 151                     get_addr_from_url(url, &addr, &s );
 152                     host.clear();
 153                     host = s; 
 154                     delete [] s;
 155                     return ;
 156 mday         1.1  }
 157                   
 158 mday         1.4  PEGASUS_EXPORT Boolean get_addr_from_url(const Sint8 *url, struct sockaddr_in *addr, Sint8 **host)
 159 mday         1.1  {
 160                     Sint8 *bptr, *url_dup;
 161                     Boolean ccode = false;
 162                   
 163                     // isolate the host field 
 164 mday         1.4    bptr = (url_dup = strdup(url));
 165 mday         1.1    if(bptr == NULL)
 166                       return(false );
 167                   
 168                     while( (*bptr != '/') && (*bptr != 0x00) )
 169                       bptr++;
 170                   
 171                     if(*bptr == '/' && *(bptr + 1) == '/') {
 172                       Sint8 *endptr, *portptr;
 173                       endptr = bptr + 2;
 174                       while (*endptr != 0x00 && *endptr != '/' && *endptr != ';')
 175                         endptr++;
 176                       *endptr = 0x00;
 177                       portptr = (endptr - 1) ;
 178                   
 179                       while( ( portptr > ( bptr + 2 ) ) && ( *portptr != ':' ) )
 180                         portptr--;
 181                   
 182                       if( *portptr == ':') {
 183                         *portptr = 0x00;
 184                         portptr++;
 185                       } else { portptr = NULL; }
 186 mday         1.1      
 187                       // bptr points to the host name or address
 188                       // portptr points to the port or is null
 189                   
 190 mday         1.4      bptr += 2;
 191                   
 192                       if(host != NULL) {
 193                         *host = new Sint8[ strlen(bptr) + strlen(portptr) + 3] ;
 194                         strcpy(*host, bptr);
 195                         strcat(*host, ":");
 196                         strcat(*host, portptr);
 197                       }
 198 mday         1.1      if (portptr != NULL)
 199                         addr->sin_port = htons( (Sint16)strtoul(portptr, NULL, 0) );
 200                       else
 201                         addr->sin_port = 0x0000;
 202                       addr->sin_family = AF_INET;
 203                       
 204 mday         1.4  
 205 mday         1.1      addr->sin_addr.s_addr = inet_addr(bptr);
 206                       if(addr->sin_addr.s_addr == INADDR_NONE) {
 207                         struct hostent *host;
 208                         struct hostent hostbuf;
 209                         Uint8 *temp ;
 210                         Uint32 result, err;
 211                         size_t hostbuflen = 256;
 212                         
 213                         // hopefully a hostname because dotted decimal notation was invalid
 214                         // look for the user@hostname production
 215                         Sint8 *userptr;
 216                         userptr = bptr;
 217                         while( (*userptr != 0x00 ) && (*userptr != '@' ) )
 218                   	userptr++;
 219                         if( *userptr == '@' )
 220                   	bptr = userptr + 1;
 221                         
 222                         temp = (Uint8 *)malloc(hostbuflen); 
 223                         if(temp != NULL) {
 224                   	host = NULL;
 225 mike         1.5  	while(temp != NULL && (result = gethostbyname_r(bptr, &hostbuf, 
 226                   	    (char *)temp, 
 227                   	    hostbuflen, 
 228                   	    &host, (int *)&err)) == ERANGE){
 229 mday         1.1  	  hostbuflen *= 2;
 230                   	  temp = (Uint8 *)realloc(temp, hostbuflen);
 231                   	}
 232                   	if(host != NULL) {
 233                   	  struct in_addr *ptr;
 234                   	  if (((ptr = (struct in_addr *)*(host->h_addr_list)) != NULL ) ) {
 235                   	    addr->sin_addr.s_addr = ptr->s_addr;
 236                   	    ccode = true;
 237                   	  }
 238                   	}
 239                   	free(temp);
 240                         } /* we allocated the temp buffer for gethostbyname */
 241                       } else { ccode = true; } /* host field is not in a valid dotted decimal form */
 242                     } /* isolated the host field in the url  */
 243                     return(ccode);
 244                   }
 245                    
 246                   
 247 mday         1.4  
 248                   static int slp_get_local_interfaces(Uint32 **list)
 249                   {
 250                     SOCKET sock;
 251                     int interfaces = 0;
 252                   
 253                     delete [] *list;
 254                   
 255                   #ifdef PEGASUS_OS_TYPE_WINDOWS
 256                   
 257                     if ( INVALID_SOCKET != ( sock  = WSASocket(AF_INET,
 258                   					   SOCK_RAW, 0, NULL, 0, 0) ) ) {
 259                       char *output_buf = new char[1024];
 260                       DWORD buf_size = 1024, bytes_returned = 0;
 261                   
 262                       if ( 0 == WSAIoctl( sock, SIO_ADDRESS_LIST_QUERY, NULL, 0, 
 263                   			output_buf, buf_size, &bytes_returned, NULL, NULL) ) {
 264                         socket_addr_list *addr_list = (socket_addr_list *)output_buf;
 265                         *list = new Uint32 [ addr_list->count + 1 ] ;
 266                         socket_addr *addr = addr_list->list;
 267                         Uint32 *intp;
 268 mday         1.4        sockaddr_in *sin;
 269                         for( interfaces = 0, intp = *list, sin = (sockaddr_in *)addr ; 
 270                   	   interfaces < addr_list->count; 
 271                   	   interfaces++ , intp++  ) {
 272                   	*intp = sin->sin_addr.s_addr;
 273                   	addr++;
 274                   	sin = (sockaddr_in *)addr;
 275                         }
 276                         *intp = INADDR_ANY;
 277                       }
 278                       delete [] output_buf;
 279                       _LSLP_CLOSESOCKET(sock);
 280                     }
 281                     
 282                   #else
 283                     if( -1 < (sock = socket(AF_INET, SOCK_DGRAM, 0) ) ) {
 284                       struct ifconf conf;
 285                   
 286                       conf.ifc_buf = new char [ 128 * sizeof(struct ifreq )  ];
 287                       conf.ifc_len = 128 * sizeof( struct ifreq ) ;
 288                       if( -1 < ioctl(sock, SIOCGIFCONF, &conf ) ) {
 289 mday         1.4        
 290                         // count the interfaces 
 291                   
 292                   
 293                         struct ifreq *r = conf.ifc_req;
 294                         struct sockaddr_in *addr ;
 295 mike         1.6        addr = SOCKADDR_IN_CAST&r->ifr_addr;
 296 mday         1.4        while(  addr->sin_addr.s_addr != 0 ) {
 297                   	interfaces++;
 298                   	r++;
 299 mike         1.6  	addr = SOCKADDR_IN_CAST&r->ifr_addr;
 300 mday         1.4        }
 301                   
 302                         // now store the addresses
 303                   
 304                         *list  = new Uint32 [interfaces + 1 ];
 305                         Uint32 *this_addr = *list;
 306                         r = conf.ifc_req;
 307 mike         1.6        addr = SOCKADDR_IN_CAST&r->ifr_addr;
 308 mday         1.4        while(  addr->sin_addr.s_addr != 0 ) {
 309                   	*this_addr = addr->sin_addr.s_addr;
 310                   	r++;
 311                   	this_addr++;
 312 mike         1.6  	addr = SOCKADDR_IN_CAST&r->ifr_addr;
 313 mday         1.4        }
 314                         *this_addr = INADDR_ANY;
 315                       } // did the ioctl 
 316                       delete [] conf.ifc_buf;
 317                       _LSLP_CLOSESOCKET(sock);
 318                     } // opened the socket 
 319                   
 320                   #endif 
 321                     // failsafe if the ioctl doesn't work
 322                     if( interfaces == 0 ) {
 323                       *list = new Uint32 [1] ;
 324                       *list[0] = INADDR_ANY; 
 325                     }
 326                   
 327                     return(interfaces);
 328                   }
 329                   
 330                   
 331                   static Boolean  slp_join_multicast(SOCKET sock, Uint32 addr) 
 332 mday         1.2  {
 333                     
 334                     // don't join on the loopback interface
 335 mday         1.4    if (addr == inet_addr("127.0.0.1") )
 336 mday         1.2      return(false);
 337                   
 338                     struct ip_mreq mreq;
 339                     mreq.imr_multiaddr.s_addr = inet_addr("239.255.255.253");
 340 mday         1.4    mreq.imr_interface.s_addr = addr;
 341 chuck        1.15 
 342                   #ifndef PEGASUS_OS_OS400  
 343                     if(SOCKET_ERROR == setsockopt(sock,IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char *)&mreq, sizeof(mreq)))
 344                   #else
 345                     if(SOCKET_ERROR == setsockopt(sock,IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)))
 346                   #endif 
 347 mday         1.2      return(false);
 348                     return(true);
 349                   }
 350                   
 351                   
 352                   
 353                   static int slp_join_multicast_all(SOCKET sock)
 354                   {
 355                   
 356 mday         1.4    Uint32 *list = NULL , *lptr = NULL;
 357                     int num_interfaces = slp_get_local_interfaces(&list);
 358                     lptr = list;
 359                     while ( *lptr != INADDR_ANY ) {
 360                       slp_join_multicast(sock, *lptr) ;
 361                       lptr++;
 362                     }
 363                     delete [] list;
 364 mday         1.2    return(num_interfaces);
 365                   }
 366                   
 367                   
 368 mday         1.4  static SOCKET slp_open_listen_sock( void )
 369 mday         1.2  {
 370                   
 371                     SOCKET sock  = socket(AF_INET, SOCK_DGRAM, 0) ;
 372                     int err = 1;
 373 chuck        1.15 #ifndef PEGASUS_OS_OS400
 374 mday         1.2    setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&err, sizeof(err));
 375 chuck        1.15 #else
 376                     setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&err, sizeof(err));
 377                   #endif
 378 mday         1.2    struct sockaddr_in local;
 379                     local.sin_family = AF_INET;
 380                     local.sin_port = htons(427);
 381                     local.sin_addr.s_addr  = INADDR_ANY;
 382 mike         1.6    if( 0 == bind(sock, SOCKADDR_CAST&local, sizeof(local)) )
 383 mday         1.4      slp_join_multicast_all(sock);
 384 mday         1.2    return(sock);
 385                   }
 386                   
 387 mday         1.1  
 388 mday         1.4  static Boolean slp_scope_intersection(const Sint8 *our_scopes, Sint8 *his_scopes)
 389                   {
 390                     const Sint8 delimiters [] = " ," ;
 391                     Sint8 *saveptr = NULL, *bptr;
 392                   
 393                     if(our_scopes == NULL || his_scopes == NULL)
 394                       return(true);
 395                     bptr = _LSLP_STRTOK(his_scopes, delimiters, &saveptr);
 396                     while (NULL != bptr) {
 397                   
 398                       // convert hist scope string  upper case
 399                       for( Sint8 *cp = bptr; *cp; ++cp) {
 400                         if( 'a' <= *cp && *cp <= 'z' )
 401                   	*cp += 'A' - 'a' ;
 402                       }
 403                   
 404                       if( NULL != strstr( bptr , our_scopes) )
 405                         return(true);
 406                       bptr = _LSLP_STRTOK(NULL, delimiters, &saveptr);
 407                     }
 408                     return(false);
 409 mday         1.4  }
 410                   
 411                   
 412 mday         1.1  // static class members (windows only )
 413                   #ifdef _WIN32
 414                    int slp_client::_winsock_count = 0;
 415                    WSADATA slp_client::_wsa_data ;
 416                   #endif 
 417                   
 418 mday         1.2  
 419                   // insert new node at the back of the list 
 420                   template<class L> void slp2_list<L>::insert(L *element)
 421 mday         1.1  {
 422                     slp2_list *ins = new slp2_list(false);
 423                     ins->_rep = element;
 424 mday         1.2    ins->_next = this;
 425                     ins->_prev = this->_prev;
 426                     this->_prev->_next = ins;
 427                     this->_prev = ins;
 428 mday         1.1    _count++;
 429                     return;
 430                   }
 431                   
 432                   
 433 kumpf        1.10 template<class L> inline L *slp2_list<L>::next(const L * init) 
 434 mday         1.1  {
 435                     if( init == NULL )
 436                       _cur = _next;
 437                     else {
 438 mike         1.5      assert( (init = _cur->_rep) != 0 );
 439 mday         1.1      _cur = _cur->_next;
 440                     }
 441                     return(_cur->_rep);
 442                   }
 443                   
 444 kumpf        1.10 template<class L> inline L *slp2_list<L>::prev( const L * init  )
 445 mday         1.1  {
 446                     if( init == NULL ) 
 447                       _cur = _next;
 448                     else {
 449                       assert( init = _cur->rep ) ;
 450                       _cur = _cur->_prev;
 451                     }
 452                     return(_cur->_rep);
 453                   }
 454                   
 455                   template<class L> inline int slp2_list<L>::count(void) { return(_count) ; }
 456                   
 457                   template<class L> void slp2_list<L>::empty_list(void) 
 458                   {
 459                     while( _count > 0 ) {
 460                       slp2_list *temp = _next;
 461                       temp->unlink();
 462                       if(temp->_rep != NULL)
 463                         delete temp->_rep;
 464                       delete temp;
 465                       _count--;
 466 mday         1.1    }
 467                     assert(_count == 0);
 468                     return;
 469                   }
 470                   
 471                   
 472                   template<class L> L *slp2_list<L>::remove( void )
 473                   {
 474                     L *ret = NULL;
 475                     if( _count > 0 ) {
 476                       slp2_list *temp = _next;
 477                       temp->unlink();
 478                       ret = temp->_rep;
 479                       // unhinge ret from temp so it doesn't get destroyed 
 480                       temp->_rep = NULL ;
 481                       delete temp;
 482                       _count--;
 483                     }
 484                     return(ret);
 485                   }
 486                   
 487 mday         1.2  
 488 kumpf        1.10 template<class L> L *slp2_list<L>::remove(const Sint8 *key)
 489 mday         1.2  {
 490                     L *ret = NULL;
 491                     if( _count > 0 ) {
 492                       slp2_list *temp = _next;
 493                       while ( temp->_isHead == false ) {
 494                         if( temp->_rep->operator==( key )) {
 495                   	temp->unlink();
 496                   	ret = temp->_rep;
 497                   	temp->_rep = NULL;
 498                   	delete temp;
 499                   	_count--;
 500                   	break;
 501                         }
 502                         temp = temp->_next;
 503                       }
 504                     }
 505                     return(ret);
 506                   }
 507                   
 508                   
 509 kumpf        1.10 template<class L> L *slp2_list<L>::reference(const Sint8 *key)
 510 mday         1.4  {
 511                     if( _count > 0 ) {
 512                       slp2_list *temp = _next;
 513                       while(temp->_isHead == false ) {
 514                         if( temp->_rep->operator==(key))
 515                   	return(temp->_rep);
 516                         temp = temp->_next;
 517                       }
 518                     }
 519                     return(NULL);
 520                   }
 521                   
 522 kumpf        1.10 template<class L> Boolean slp2_list<L>::exists(const Sint8 *key)
 523 mday         1.2  {
 524                     if( _count > 0) {
 525                       slp2_list *temp = _next;
 526                       while(temp->_isHead == false ) {
 527                         if( temp->_rep->operator==( key ))
 528                   	return(true);
 529                         temp = temp->_next;
 530                       }
 531                     }
 532                     return(false);
 533                   }
 534                   
 535                   
 536 mday         1.1  da_list::~da_list()
 537                   {
 538                     //  unlink();
 539 mday         1.2    delete[] url;
 540                     delete[] scope;
 541                     delete[] attr;
 542                     delete[] spi;
 543                     delete[] auth;
 544 mday         1.1  }
 545                   
 546                   
 547 mday         1.2  Boolean da_list::operator ==(const Sint8 *key) const
 548                   {
 549                     if( ! strcasecmp(url, key) ) 
 550                       return(true);
 551                     return(false);
 552                   }
 553 mday         1.1  
 554                   rply_list::~rply_list()
 555                   {
 556                     //  unlink();
 557 mday         1.2    delete[] url;
 558                     delete[] auth;
 559                   }
 560                   
 561                   
 562                   Boolean rply_list::operator ==(const Sint8 *key ) const 
 563                   {
 564                     if (! strcasecmp(url, key) )
 565                       return(true);
 566                     return(false);
 567                   }
 568                   
 569                   
 570 kumpf        1.10 reg_list::reg_list(const Sint8 *r_url, 
 571                   		   const Sint8 *r_attributes, 
 572                   		   const Sint8 *r_service_type, 
 573                   		   const Sint8 *r_scopes, 
 574 mday         1.4  		   time_t r_lifetime)
 575                   {
 576                     if( r_url != NULL ) {
 577                       url = new Sint8[ strlen(r_url + 1 ) ];
 578                       strcpy(url, r_url);
 579                     }
 580                   
 581                     if( r_attributes != NULL ) {
 582                       attributes = new Sint8[ strlen(r_attributes) + 1 ];
 583                       strcpy(attributes, r_attributes);
 584                     }
 585                   
 586                     if(r_service_type != NULL ) {
 587                       service_type = new Sint8[ strlen(r_service_type) + 1 ]; 
 588                       strcpy(service_type, r_service_type);
 589                     }
 590                   
 591                     if(r_scopes != NULL) {
 592                       scopes = new Sint8[ strlen(r_scopes ) + 1 ];
 593                       strcpy(scopes, r_scopes);
 594                     }
 595 mday         1.4    lifetime = r_lifetime;
 596                   
 597                   }
 598                   
 599 mday         1.2  reg_list::~reg_list()
 600                   {
 601                     delete[] url;
 602                     delete[] attributes;
 603                     delete[] service_type;
 604                     delete[] scopes;
 605                   }
 606                   
 607                   
 608                   Boolean reg_list::operator ==(const Sint8 *key ) const
 609                   {
 610                     if( ! strcasecmp(url, key) )
 611                       return(true);
 612                     return(false);
 613 mday         1.1  }
 614                   
 615 mday         1.4  url_entry::url_entry( Uint16 u_lifetime,
 616                   		      Sint8 *u_url, 
 617                   		      Uint8 u_num_auths,
 618                   		      Uint8 *u_auth_blocks)
 619                   {
 620                   
 621                     lifetime = u_lifetime;
 622                     if(u_url != NULL && (len = strlen(u_url) )) {
 623                       len++;
 624                       url = new Sint8[len];
 625                       strcpy(url, u_url);
 626                     } else { len = 0 ; }
 627                   
 628                     num_auths = 0;
 629                     auth_blocks = NULL;
 630                   }
 631                   
 632                   url_entry::~url_entry() 
 633                   {
 634                     delete [] url;
 635                     delete [] auth_blocks;
 636 mday         1.4  }
 637                   
 638                   
 639                   Boolean url_entry::operator ==(const Sint8 *key) const
 640                   {
 641                     if( ! strcasecmp(url, key) )
 642                       return(true);
 643                     return(false);
 644                   }
 645                   
 646 mday         1.1  
 647                   void slp_client::set_target_addr(const Sint8 *addr)
 648                   {
 649                     if(addr == NULL)
 650                       _target_addr = inet_addr("239.255.255.253") ;
 651 chuck        1.15   else
 652                   #ifndef PEGASUS_OS_OS400
 653 mday         1.1      _target_addr = inet_addr(addr);
 654 chuck        1.15 #else
 655                       _target_addr = inet_addr((char *)addr);
 656                   #endif
 657 mday         1.1  }
 658                   
 659                   void slp_client::set_local_interface(const Sint8 *iface)
 660                   {
 661                   
 662                     if(iface == NULL)
 663                       _local_addr = INADDR_ANY;
 664                     else
 665 chuck        1.15 #ifndef PEGASUS_OS_OS400
 666 mday         1.1      _local_addr = inet_addr(iface);
 667 chuck        1.15 #else
 668                       _local_addr = inet_addr((char *)iface);
 669                   #endif
 670 mday         1.1  }
 671                   
 672                   void slp_client::set_spi(const Sint8 *spi) 
 673                   {
 674 mday         1.4    delete [] _spi;
 675                     if(spi != NULL && strlen(spi) ) {
 676                       _spi = new Sint8[strlen(spi) + 1 ];
 677                       strcpy(_spi, spi);
 678                     }
 679 mday         1.1    return ;
 680                   }
 681                   
 682 mday         1.4  void slp_client::set_scopes(const Sint8 *scopes)
 683                   {
 684                     delete [] _scopes;
 685                     if( scopes != NULL && strlen(scopes) ) {
 686                       _scopes = new Sint8[ strlen(scopes) + 1 ];
 687                       strcpy(_scopes, scopes);
 688                     }
 689                     return;
 690                   }
 691                   
 692 mday         1.1  slp_client::slp_client(const Sint8 *target_addr, 
 693                   		       const Sint8 *local_addr, 
 694                   		       Uint16 target_port, 
 695 mday         1.4  		       const Sint8 *spi, 
 696                   		       const Sint8 *scopes )
 697 mday         1.1  
 698 mike         1.7    : _pr_buf_len(0), _buf_len (LSLP_MTU), _version((Uint8)1),
 699 mday         1.4      _xid(1),  _target_port(htons(target_port)), _local_addr_list(NULL), 
 700                       _spi(NULL), _scopes(NULL),  _use_das(false), _last_da_cycle(0), _retries(3), 
 701                       _ttl(255),  _convergence(5), _crypto_context(NULL), das( ), 
 702                       replies( ), regs( )
 703 mday         1.1  
 704                   {
 705                     set_target_addr(target_addr);
 706                     set_local_interface(local_addr);
 707                     set_spi(spi);
 708 mday         1.4    set_scopes(scopes);
 709 mday         1.2    _pr_buf = new Sint8[LSLP_MTU];
 710                     _msg_buf = new Sint8[LSLP_MTU] ; 
 711                     _rcv_buf = new Sint8[LSLP_MTU] ;
 712 mday         1.4    _tv.tv_sec = 0;
 713                     _tv.tv_usec = 200000;
 714 mday         1.1  #ifdef _WIN32
 715                     if(_winsock_count == 0)
 716                       WSAStartup(0x0002, &_wsa_data);
 717                     _winsock_count++;
 718                   #endif 
 719 mday         1.2  
 720 mday         1.4    // build our local address list
 721                     slp_get_local_interfaces( &_local_addr_list ) ;
 722                   
 723                     // before opening the listen socket we need to see if the local machine is a da
 724                     // if it is, don't open the listen socket
 725                     _rcv_sock = INVALID_SOCKET;
 726                     local_srv_req(NULL, NULL, "DEFAULT");
 727                     if(0 < das.count() )
 728                       _rcv_sock = INVALID_SOCKET;
 729                     else
 730                       _rcv_sock = slp_open_listen_sock( );
 731 mday         1.1  }
 732                   
 733                   
 734                   slp_client::~slp_client()
 735                   {
 736 mday         1.2    // close the receive socket 
 737 mday         1.4    _LSLP_CLOSESOCKET( _rcv_sock ) ;
 738 mday         1.2  #ifdef _WIN32
 739                     _winsock_count--;
 740                     if(_winsock_count == 0)
 741                       WSACleanup();
 742                   #endif 
 743                   
 744 mday         1.4    delete [] _pr_buf;
 745                     delete [] _msg_buf;
 746                     delete [] _rcv_buf;
 747                     delete [] _local_addr_list;
 748                     delete [] _spi;
 749                     delete [] _scopes;
 750                   
 751 mday         1.1    if(_crypto_context != NULL)
 752                       free(_crypto_context);
 753                     das.empty_list();
 754                     replies.empty_list();
 755                   }
 756                   
 757                   
 758                   void slp_client::prepare_pr_buf(const Sint8 *a)
 759                   {
 760                     if(a == NULL)
 761                       return;;
 762                     if(_pr_buf_len > 0) 
 763                       *(_pr_buf + _pr_buf_len - 1) = ',' ;
 764                     do {
 765                       *(_pr_buf + _pr_buf_len) = *a;
 766                       a++;
 767                       _pr_buf_len++;
 768                     }while((*a != 0x00) && (_pr_buf_len < LSLP_MTU - 1)); 
 769                     _pr_buf_len++;
 770                   }
 771                   
 772 mday         1.1  Boolean slp_client::prepare_query( Uint16 xid,
 773                   				const Sint8 *service_type,
 774                   				const Sint8 *scopes, 
 775                   				const Sint8 *predicate  ) 
 776                   {
 777                     Sint16 len, total_len;
 778                     Sint8 *bptr;
 779                     if(_msg_buf == NULL || _pr_buf == NULL)
 780                       return(false);
 781                     if(xid != _xid) {
 782                       /* this is a new request */
 783                       memset(_pr_buf, 0x00, LSLP_MTU);
 784                       _pr_buf_len = 0;
 785                       _xid = xid;
 786                     }
 787                     memset(_msg_buf, 0x00, LSLP_MTU);
 788                     bptr = _msg_buf;
 789                     _LSLP_SETVERSION(bptr, LSLP_PROTO_VER);
 790                     _LSLP_SETFUNCTION(bptr, LSLP_SRVRQST);
 791                     /* we don't know the length yet */
 792 mday         1.4    _LSLP_SETFLAGS(bptr, 0);
 793 mday         1.1    _LSLP_SETXID(bptr, xid);
 794                     _LSLP_SETLAN(bptr, LSLP_EN_US);
 795                     bptr += ( total_len = _LSLP_HDRLEN(bptr) ) ;
 796                       
 797                     if(_pr_buf_len + total_len < LSLP_MTU) {
 798                       /* set the pr list length */
 799                       _LSLP_SETSHORT(bptr, (len = _pr_buf_len), 0);
 800                       if(len)
 801                         memcpy(bptr + 2, _pr_buf, len);
 802                       total_len += ( 2 + len );
 803                       bptr += (2 + len);
 804                   		
 805                       if(service_type == NULL)
 806                         len = DA_SRVTYPELEN;
 807                       else
 808                         len = strlen(service_type) + 1;
 809                       if(total_len + 2 + len < LSLP_MTU) {
 810                         /* set the service type string length */
 811                         _LSLP_SETSHORT(bptr, len, 0);
 812                         if(service_type != NULL)
 813                   	memcpy(bptr + 2, service_type, len);
 814 mday         1.1        else
 815                   	memcpy(bptr + 2, DA_SRVTYPE, len);
 816                   	  	  
 817                         total_len += (2 + len);
 818                         bptr += (2 + len);
 819                   
 820                         /* set the scope len and scope type, advance the buffer */
 821                   	  
 822                         if(scopes == NULL)
 823                   	len = DA_SCOPELEN;
 824                         else
 825                   	len = strlen(scopes) + 1;
 826                         if( total_len + 2 + len < LSLP_MTU) {
 827                   	_LSLP_SETSHORT(bptr, len, 0);
 828                   	if(scopes != NULL) 
 829                   	  memcpy(bptr + 2, scopes, len);
 830                   	else
 831                   	  memcpy(bptr + 2, DA_SCOPE, DA_SCOPELEN);
 832                   
 833                   	total_len += ( 2 + len);
 834                   	bptr += (2 + len);
 835 mday         1.1  
 836                   	/* stuff the predicate if there is one  */
 837                   	if(predicate == NULL)
 838                   	  len = 0;
 839                   	else
 840                   	  len = strlen(predicate) + 1;
 841                   	if( total_len + 2 + len < LSLP_MTU) {
 842                   	  _LSLP_SETSHORT(bptr, len, 0);
 843                   	  if(predicate != NULL)
 844                   	    memcpy(bptr + 2, predicate, len);
 845                   	      
 846                   	  total_len += (2 + len);
 847                   	  bptr += (2 + len);
 848                   	      
 849                   	  /* stuff the spi */
 850                   	      
 851                   	  /* set the spi len and spi string */
 852                   	  if(_spi == NULL)
 853                   	    len = 0;
 854                   	  else
 855                   	    len = strlen(_spi) + 1;
 856 mday         1.1  	      
 857                   	  if(total_len + 2 + len < LSLP_MTU) {
 858                   	    _LSLP_SETSHORT(bptr, len, 0);
 859                   		
 860                   	    if(_spi != NULL)
 861                   	      memcpy(bptr + 2, _spi, len);
 862                   		
 863                   	    total_len += ( 2 + len);
 864                   	    bptr += (2 + len);
 865                   	    assert(total_len == bptr - _msg_buf);
 866                   	    /* now go back and set the length for the entire message */
 867                   	    _LSLP_SETLENGTH(_msg_buf, total_len );
 868                   	    return(true);
 869                   	  } /* room for the spi  */
 870                   	} /*  room for predicate  */
 871                         } /* room for the scope  */
 872                       } /* room for the service type  */
 873                     } /* room for the pr list  */
 874                     return(false);
 875                   }
 876                   
 877 mday         1.1  
 878                   rply_list *slp_client::get_response( void  )
 879                   {
 880                     
 881 mday         1.4    return(replies.remove());
 882 mday         1.1  }
 883                   
 884                   
 885                   int slp_client::find_das(const Sint8 *predicate, 
 886                   			 const Sint8 *scopes)
 887                   {
 888                     converge_srv_req(NULL, predicate, scopes);
 889 mday         1.2    time(&_last_da_cycle);
 890                     if(0 < das.count() )
 891                       _use_das = true;
 892                     else
 893                       _use_das = false;
 894 mday         1.1    return( das.count( ) );
 895                   }
 896                   
 897 mday         1.4  
 898                   // smart interface to slp discovery. uses das if they are present, 
 899                   // convergence otherwise.
 900                   // periodically forces an active da discovery cycle 
 901                   
 902                   void slp_client::discovery_cycle ( const Sint8 *type, 
 903                   				   const Sint8 *predicate, 
 904                   				   const Sint8 *scopes) 
 905                   
 906                   {
 907                     // see if we have built a cache of directory agents 
 908                     if(  0 == das.count() ) {
 909                       // we don't know of any directory agents - see if we need to do active da discovery
 910                       if( ((time(NULL)) - _last_da_cycle ) > (60 * 5) )
 911                         find_das(NULL, scopes) ;
 912                     }
 913                   
 914                     // if there are das, unicast a srvreq to each da
 915                   
 916                     if( 0 < das.count() ) {
 917                   
 918 mday         1.4      da_list *da = das.next(NULL);
 919                       struct sockaddr_in addr;
 920                       while( da != NULL ) {
 921                         addr.sin_port = htons(427);
 922                         addr.sin_family = AF_INET;
 923                         addr.sin_addr.s_addr = inet_addr(da->remote);
 924                         unicast_srv_req(type, predicate, scopes, &addr);
 925                         da = das.next(da);
 926                       }
 927                     } else {
 928                       // do a convergence request because we don't have any das to use 
 929                   
 930                       converge_srv_req(type, predicate, scopes );
 931                     }
 932                     return; 
 933                   }
 934                   
 935                   // this request MUST be retried <_convergence> times on EACH interface 
 936                   // regardless of how many responses we have received 
 937                   // it can be VERY time consuming but is the most thorough 
 938                   // discovery method 
 939 mday         1.4  void slp_client::converge_srv_req( const Sint8 *type, 
 940                   				   const Sint8 *predicate, 
 941                   				   const Sint8 *scopes)
 942                   {
 943                   
 944                     Uint32 old_target_addr = _target_addr;
 945                     Uint32 old_local_addr = _local_addr;
 946                     set_target_addr( "239.255.255.253" ) ;
 947                     
 948                     Uint32 *p_addr = _local_addr_list;
 949                     Uint16 convergence; 
 950                     Uint32 loopback = inet_addr("127.0.0.1");
 951                   
 952                     do {
 953                       if( *p_addr == loopback ) {
 954                         p_addr++;
 955                         continue; 
 956                       }
 957                       _local_addr = *p_addr;
 958                       convergence = _convergence;
 959                   
 960 mday         1.4      if(prepare_query( _xid + 1, type, scopes, predicate)) {
 961                   	_LSLP_SETFLAGS(_msg_buf, LSLP_FLAGS_MCAST) ;
 962                   	send_rcv_udp( );
 963                         }
 964                   
 965                       while(--convergence > 0) {
 966                         if(prepare_query( _xid, type, scopes, predicate)) {
 967                   	_LSLP_SETFLAGS(_msg_buf, LSLP_FLAGS_MCAST) ;
 968                   	send_rcv_udp( );
 969                         }
 970                       }
 971                       p_addr++;
 972                     }   while( *p_addr != INADDR_ANY ) ;
 973                   
 974                   
 975                     // always try a local request
 976                     local_srv_req(type, predicate, scopes);
 977                   
 978                     _target_addr = old_target_addr;
 979                     _local_addr = old_local_addr;
 980                     return ;
 981 mday         1.4  }
 982                   
 983                   
 984                   
 985                   // this request will be retried MAX <_retries> times 
 986                   // but will always end when the first response is received
 987                   // This request is best when using a directory agent
 988                   void slp_client::unicast_srv_req( const Sint8 *type, 
 989 mday         1.1  				  const Sint8 *predicate, 
 990 mday         1.4  				  const Sint8 *scopes, 
 991                   				  struct sockaddr_in *addr )
 992                   {
 993                   
 994                     Uint32 target_addr_save, local_addr_save;
 995                     Uint16 target_port_save;
 996                     struct timeval tv_save;
 997                     
 998                     target_addr_save = _target_addr;
 999                     local_addr_save = _local_addr;
1000                     target_port_save = _target_port;
1001                   
1002                     tv_save.tv_sec = _tv.tv_sec;
1003                     _tv.tv_sec = 1;
1004                     
1005                     // let the host decide which interface to use 
1006                     _local_addr = INADDR_ANY; 
1007                     _target_addr = addr->sin_addr.s_addr;
1008                     _target_port = addr->sin_port;
1009                   
1010                     
1011 mday         1.4    int retries = _retries ;
1012                     int old_count = replies.count() ;
1013                     srv_req(type, predicate, scopes, false) ;
1014                     while( --retries > 0 && replies.count() == old_count ) {
1015                       srv_req(type, predicate, scopes, true );
1016                     }
1017                     _target_addr = target_addr_save;
1018                     _local_addr = local_addr_save;
1019                     _target_port = target_port_save;
1020                     _tv.tv_sec = tv_save.tv_sec;
1021                     return;
1022                   }
1023                   
1024                   // this request is targeted to the loopback interface, 
1025                   // and has a tiny wait timer. It should be resolved quickly. 
1026                   // It will never be retried.
1027                   void slp_client::local_srv_req( const Sint8 *type, 
1028                   				const Sint8 *predicate, 
1029                   				const Sint8 *scopes )
1030                   
1031                   
1032 mday         1.1  {
1033                   
1034 mday         1.4    Uint32 target_addr_save;
1035                     struct timeval tv_save;
1036                     
1037                     target_addr_save = _target_addr;
1038                   
1039                     tv_save.tv_sec = _tv.tv_sec;
1040                     tv_save.tv_usec = _tv.tv_usec;
1041                     _tv.tv_sec = 0;
1042                     _tv.tv_usec = 1000000;
1043                     
1044                     // let the host decide which interface to use 
1045                     _local_addr = INADDR_ANY; 
1046                     _target_addr = inet_addr("127.0.0.1");
1047                     _target_port = htons(427);
1048                   
1049 mday         1.1    
1050 mday         1.4    srv_req(type, predicate, scopes, false) ;
1051                   
1052                     _target_addr = target_addr_save;
1053                   
1054                     _tv.tv_sec = tv_save.tv_sec;
1055                     _tv.tv_usec = tv_save.tv_usec;
1056                     return;
1057                   
1058 mday         1.1  }
1059                   
1060                   
1061 mday         1.4  // workhorse request function
1062 mday         1.1  void slp_client::srv_req( const Sint8 *type, 
1063                   			  const Sint8 *predicate, 
1064 mday         1.4  			  const Sint8 *scopes, 
1065                   			  Boolean retry )
1066 mday         1.1  {
1067 mday         1.4    if ((true == prepare_query( (retry == true) ? _xid : _xid + 1, 
1068                   			      type, 
1069                   			      scopes, 
1070                   			      predicate ))) {
1071 mday         1.1      send_rcv_udp(  ) ;
1072                     } /* prepared query  */
1073                     return ;
1074                   }
1075                   
1076 mday         1.4  void slp_client::decode_msg( struct sockaddr_in *remote )
1077 mday         1.1  {
1078                     
1079 mday         1.2    if( _xid == _LSLP_GETXID( _rcv_buf ))
1080                       prepare_pr_buf( inet_ntoa(remote->sin_addr) );
1081                   
1082                     Sint8 function = _LSLP_GETFUNCTION( _rcv_buf );
1083                     switch(function) {
1084                     case LSLP_DAADVERT:
1085                       decode_daadvert( remote );
1086                       return;		
1087 mday         1.4    case LSLP_SRVRQST:
1088                       decode_srvreq( remote );
1089                       return;
1090 mday         1.2    case LSLP_SRVRPLY:
1091                       decode_srvrply( remote );
1092                       return;
1093                     case LSLP_SRVACK:
1094                     default:
1095                       break;
1096                     }
1097 mday         1.1    return;
1098                   }
1099                   
1100                   
1101                   void slp_client::decode_srvrply( struct sockaddr_in *remote )
1102                   {
1103                     Sint8 *bptr;
1104                     Sint16 str_len, err, count;
1105                     Sint32 total_len, purported_len;
1106                   
1107 mday         1.2    bptr = _rcv_buf;
1108 mday         1.1    purported_len = _LSLP_GETLENGTH(bptr);
1109                     bptr += (total_len = _LSLP_HDRLEN(bptr));
1110                     if(total_len < purported_len) {
1111                       rply_list *reply = new rply_list();
1112                       if(reply == NULL) abort();
1113                       err = _LSLP_GETSHORT(bptr, 0);
1114                       count = _LSLP_GETSHORT(bptr, 2);
1115                       bptr += 4;
1116                       total_len += 4;
1117                       /* loop on the url entries  */
1118                       while( ( total_len <= purported_len ) && ( count > 0 ) && reply != NULL ) {
1119                         reply->function = LSLP_SRVRPLY;
1120                         reply->err = err;
1121                         reply->lifetime = _LSLP_GETSHORT(bptr, 1);
1122                         total_len += (5 + (str_len = _LSLP_GETSHORT(bptr, 3)));
1123                         if(total_len <= purported_len) {
1124                   	Sint8 num_auths;
1125                   	if(str_len > 0) {
1126 mday         1.2  	  reply->url = new Sint8[str_len + 1];
1127                   	  memcpy(reply->url, bptr + 5, str_len);
1128                   	  *((reply->url) + str_len) = 0x00;
1129 mday         1.1  	  bptr += (5 + str_len);
1130                   	  reply->auth_blocks = (num_auths = _LSLP_GETBYTE(bptr, 0));
1131                   	  total_len += 1;
1132                   	  bptr += 1;
1133                   	  while(num_auths && (total_len <= purported_len )) {
1134                   	    /* iterate past the authenticators for now  */
1135                   	    /* need extra code here to authenticate url entries  */
1136                   	    total_len += (str_len = _LSLP_GETSHORT(bptr, 2));
1137                   	    bptr += str_len;
1138                   	    num_auths--;
1139                   	  }
1140 mday         1.2  	  // handling duplicate responses is really inefficient, and we're 
1141                   	  // not helping things out by checking for dupes this late in the game
1142                   	  // however, in order to get to any further urls that may be in the
1143                   	  // reply buffer we need to unstuff it anyway. So we are optimizing
1144                   	  // for the case where there are no dupes. 
1145                   	  if( false == replies.exists(reply->url) ) {
1146                   	    strcpy(&(reply->remote[0]), inet_ntoa( remote->sin_addr )) ;
1147                   	    replies.insert(reply);
1148                   	  } else { delete reply ; }
1149 mday         1.1  	  count--;
1150                   	  if((total_len <= purported_len) && (count > 0) )
1151                   	    reply = new rply_list( ); 
1152                   	  else 
1153                   	    reply = NULL;
1154                   	} else { delete reply;  reply = NULL ; } /* bad packet */
1155                         } else { delete reply;  reply = NULL ; }  /*  bad packet */
1156                       } // while unwrapping multi-response message  
1157                     } /* if the hdr length field is consistent with reality */
1158                     return;
1159                   }
1160                   
1161                     
1162                   void slp_client::decode_daadvert(struct sockaddr_in *remote)
1163                   {
1164                     Sint8 *bptr;
1165                     Sint16 str_len;
1166                     Sint32 total_len, purported_len;
1167                   
1168 mday         1.2    bptr = _rcv_buf;
1169 mday         1.1    purported_len = _LSLP_GETLENGTH(bptr);
1170                     bptr += (total_len = _LSLP_HDRLEN(bptr));
1171                     if(total_len < purported_len) {
1172                       da_list *adv = new da_list( );
1173                       if(adv == NULL) abort();
1174                   
1175                       adv->function = LSLP_DAADVERT;
1176                       adv->err = _LSLP_GETSHORT(bptr, 0);
1177                       adv->stateless_boot = _LSLP_GETLONG(bptr, 2);
1178                       total_len += (8 + (str_len = _LSLP_GETSHORT(bptr, 6)));
1179                       if(total_len < purported_len) {
1180                         /* decode and capture the url  - note: this is a string, not a url-entry structure */
1181 mday         1.2        adv->url = new Sint8[str_len + 1] ;
1182                         memcpy(adv->url, bptr + 8, str_len);
1183                         *((adv->url) + str_len) = 0x00;
1184                         /* advance the pointer past the url string */
1185                         bptr += (str_len + 8);
1186                         total_len += (2 + (str_len = _LSLP_GETSHORT(bptr, 0)));
1187                         if(total_len < purported_len) {
1188                   	if(str_len > 0) {
1189                   	  adv->scope = new Sint8[str_len + 1] ;
1190                   	  memcpy(adv->scope, bptr + 2, str_len);
1191                   	  *((adv->scope) + str_len) = 0x00;
1192                   	}
1193                   	/* advance the pointer past the scope string  */
1194                   	bptr += (str_len + 2);
1195 mday         1.1  	total_len += (2 + (str_len = _LSLP_GETSHORT(bptr, 0)));
1196                   	if(total_len < purported_len) {
1197                   	  if(str_len > 0) {
1198 mday         1.2  	    adv->attr = new Sint8[str_len + 1] ;
1199                   	    memcpy(adv->attr, bptr + 2, str_len);
1200                   	    *((adv->attr) + str_len) = 0x00;
1201 mday         1.1  	  }
1202 mday         1.2  	  /* advance the pointer past the attr string */
1203 mday         1.1  	  bptr += (str_len + 2);
1204                   	  total_len += (2 + (str_len = _LSLP_GETSHORT(bptr, 0)));
1205                   	  if(total_len < purported_len) {
1206 mday         1.2  	    if(str_len > 0 ) {
1207                   	      adv->spi = new Sint8[str_len + 1];
1208                   	      memcpy(adv->spi, bptr + 2, str_len);
1209                   	      *((adv->spi) + str_len) = 0x00;
1210                   	    } /*  if there is an spi  */
1211                   		
1212                   	    /* advance the pointer past the spi string  */
1213 mday         1.1  	    bptr += (str_len + 2);
1214 mday         1.2  	    adv->auth_blocks = _LSLP_GETBYTE(bptr, 0);
1215                   	    
1216                   	    // if we already know about this da, remove the existing
1217                   	    // entry from our cache and insert this new entry
1218                   	    // maybe the stateless boot field changed or the da
1219                   	    // supports new scopes, etc. 
1220                   	    da_list * exists = das.remove(adv->url);
1221                   	    delete exists;
1222                   	      
1223                   	    /* need code here to handle authenticated urls */
1224                   	    strcpy(&(adv->remote[0]), inet_ntoa(remote->sin_addr)) ;
1225                   	    das.insert(adv); 
1226                   	    return;
1227                   	  } /*  spi length field is consistent with hdr */
1228                   	} /* attr length field is consistent with hdr */
1229                         } /*  scope length field is consistent with hdr */
1230 mday         1.1      } 
1231                     }
1232                     return;
1233                   }
1234                   
1235                   
1236 mday         1.4  void slp_client::decode_srvreq(struct sockaddr_in *remote )
1237                   {
1238                     
1239                     Sint8 *bptr;
1240                     Sint16 str_len, err = LSLP_PARSE_ERROR ;
1241                     Sint32 total_len, purported_len;
1242                   		    time_t current;
1243                     
1244                     bptr = _rcv_buf;
1245                     purported_len = _LSLP_GETLENGTH(bptr);
1246                     bptr += (total_len = _LSLP_HDRLEN(bptr));
1247                     if(total_len < purported_len) {
1248                       if( 0 < regs.count() ) {
1249                         // advance past the slp v2 header
1250                         // get the previous responder list 
1251                         str_len = _LSLP_GETSHORT(bptr, 0);
1252                         if ( (str_len + total_len + 2 < purported_len )) {
1253                   	if( false == slp_previous_responder( (str_len ? bptr + 2 : NULL ) )) {
1254                   	  Sint8 *service_type = NULL;
1255                   	  Sint8 *scopes = NULL;
1256                   	  Sint8 *spi = NULL;
1257 mday         1.4  	  slp2_list<url_entry> url_list ;
1258                   
1259                   	  bptr += 2 + str_len;
1260                   	  total_len += 2 + str_len;
1261                   	  // extract the service type string 
1262                   	  str_len = _LSLP_GETSHORT(bptr, 0);
1263                   	  if(str_len && (str_len + total_len + 2 < purported_len )) {
1264                   	    service_type = new Sint8[str_len + 1]; // one extra byte 
1265                   	    strcpy(service_type, bptr + 2);
1266                   
1267                   	    // set the error code to zero 
1268                   	    err = 0; 
1269                   	    bptr += 2 + str_len;
1270                   	    total_len += 2 + str_len;
1271                   
1272                   	    // extract the scope list
1273                   
1274                   	    str_len = _LSLP_GETSHORT(bptr, 0);
1275                   	    if( str_len + total_len + 2 < purported_len) {
1276                   	      if(str_len > 0 ) {
1277                   		scopes = new Sint8[str_len + 1] ; // one extra byte
1278 mday         1.4  		strcpy(scopes, bptr + 2);
1279                   	      }
1280                   
1281                   	      // see if the requested scopes intersect with our scopes 
1282                   
1283                   	      if (true == slp_scope_intersection(_scopes, scopes) ) {
1284                   
1285                   		bptr += 2 + str_len;
1286                   		total_len += 2 + str_len;
1287                   
1288                   		// this is a very lightweight client and currently 
1289                   		// doesn't support predicate evaluation. 
1290                   		// we will answer srvreq messages with no predicate
1291                   		// however, if there is a predicate, we can't evaluate it
1292                   		// so we won't answer it. 
1293                   
1294                   		// extract the predicate
1295                   		str_len = _LSLP_GETSHORT(bptr, 0) ;
1296                   		if(str_len == 0 ) {
1297                   		  // ignore the spi for now. 
1298                   		  // look for a srvtype match 
1299 mday         1.4  
1300                   		  reg_list *reg = regs.next(NULL);
1301                   		  while( reg != 0 ) {
1302                   		    // check the lifetime 
1303                   
1304                   		    if( (current = time(NULL)) > reg->lifetime ) {
1305                   		      // this guy is stale, unlink him and start over 
1306                   		      regs.remove(reg->url);
1307                   		      delete reg;
1308                   		      reg = regs.next(NULL);
1309                   		      continue;
1310                   		    }
1311                   		    if( ! strcasecmp( reg->service_type, service_type ) ) {
1312                   		      // found a match
1313                   		      
1314                   		      url_entry *entry = new url_entry((reg->lifetime - time(NULL) ), 
1315                   						       reg->url ) ;
1316                   		      url_list.insert(entry);
1317                   		    }
1318                   		    reg = regs.next(reg);
1319                   		  } // traversing list
1320 mday         1.4  
1321                   		} // if there is no predicate 
1322                   	      } // scopes intersect 
1323                   	    } // scope string fits
1324                   	  } // svc type string fits
1325                   	  
1326                   	  Boolean mcast = ( ((_LSLP_GETFLAGS( _rcv_buf )) & (LSLP_FLAGS_MCAST) ) ? true : false   ) ;
1327                   	  if(mcast == false || url_list.count() ) {
1328                   
1329                   	    // we need to respond to this message
1330                   	    
1331                   	    _LSLP_SETVERSION(_msg_buf, LSLP_PROTO_VER);
1332                   	    _LSLP_SETFUNCTION(_msg_buf, LSLP_SRVRPLY);
1333                   	    // skip the length for now
1334                   	    _LSLP_SETFLAGS(_msg_buf, 0);
1335                   	    _LSLP_SETNEXTEXT(_msg_buf, 0, LSLP_NEXT_EX);
1336                   	    _LSLP_SETXID( _msg_buf, ( _LSLP_GETXID(_rcv_buf)  )  );
1337                   	    _LSLP_SETLAN(_msg_buf, LSLP_EN_US );
1338                   	    Sint32 msg_len = _LSLP_HDRLEN(_msg_buf);
1339                   	    Sint8 *bptr = _msg_buf + msg_len;
1340                   	    _LSLP_SETSHORT(bptr, err, 0);
1341 mday         1.4  	    _LSLP_SETSHORT( bptr, url_list.count() , 2 );
1342                   	    
1343                   	    bptr += 4;
1344                   	    msg_len += 4;
1345                   	    while ( 0 < url_list.count() ) {
1346                   	      url_entry *entry = url_list.remove() ;
1347                   	      assert(entry != NULL);
1348                   
1349                   	      // check the length 
1350                   	      if ( (msg_len + 6 + entry->len ) <= LSLP_MTU ) {
1351                   		_LSLP_SETSHORT(bptr, entry->lifetime, 1);
1352                   		_LSLP_SETSHORT(bptr, entry->len, 3);
1353                   		memcpy(bptr + 5, entry->url, entry->len);
1354                   
1355                   		bptr += (5 + entry->len );
1356                   		msg_len += (5 + entry->len); 
1357                   
1358                   		// for now don't support authentication
1359                   		_LSLP_SETBYTE(bptr, 0, 0);
1360                   		bptr++;
1361                   		msg_len++;
1362 mday         1.4  	      
1363                   	      } else  {   
1364                   		// set the overvlow flag because we ran out of room 
1365                   		// also decrement the count of urls
1366                   		// possibly a subsequent url will fit so kee going 
1367                   		_LSLP_SETFLAGS(_msg_buf,  LSLP_FLAGS_OVERFLOW);
1368                   		Sint8 *save = bptr;
1369                   		bptr = _msg_buf + _LSLP_HDRLEN(_msg_buf) ;
1370                   		_LSLP_SETSHORT(bptr, ( _LSLP_GETSHORT(bptr, 2) - 1 ) , 2 );
1371                   		bptr = save;
1372                   	      }
1373                   	      delete entry;
1374                   	    }
1375                   
1376                   	    // ok, now we can set the length
1377                   	    _LSLP_SETLENGTH(_msg_buf, msg_len );
1378                   
1379                   	    // _msg_buf is stuffed with the service reply. now we need 
1380                   	    // to allocate a socket and send it back to the requesting node 
1381                   	    SOCKET sock;
1382                   	    if(INVALID_SOCKET != (sock = socket(AF_INET, SOCK_DGRAM, 0))) {
1383 mday         1.4  	      int err = 1;
1384 chuck        1.15 #ifndef PEGASUS_OS_OS400
1385 mday         1.4  	      setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&err, sizeof(err) );
1386 chuck        1.15 #else
1387                   	      setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&err, sizeof(err) );
1388                   #endif
1389 mday         1.4  	      struct sockaddr_in local;
1390                   	      local.sin_family = AF_INET;
1391                   	      local.sin_port = _target_port ; 
1392                   	      local.sin_addr.s_addr = _local_addr;
1393 mike         1.6  	      if(SOCKET_ERROR != bind(sock, SOCKADDR_CAST&local, sizeof(local))) {
1394 mday         1.4  		sendto(sock, _msg_buf, msg_len , 0, 
1395 mike         1.6  		      SOCKADDR_CAST(remote), sizeof(struct sockaddr_in )) ;
1396 mday         1.4  	      } // successfully bound this socket 
1397                   	      _LSLP_CLOSESOCKET(sock);
1398                   	    } // successfully opened this socket
1399                   	  } // we must respond to this request 
1400                   	  delete [] spi; 
1401                   	  delete [] scopes;
1402                   	  delete [] service_type; 
1403                   	} // not on the pr list 
1404                         } // pr list length is consistent 
1405                       } // if there are local registrations
1406                     } // if length is consistent
1407                   }
1408                   
1409                   
1410 kumpf        1.10 Boolean slp_client::srv_reg(const Sint8 *url,
1411                   			 const Sint8 *attributes,
1412                   			 const Sint8 *service_type,
1413                   			 const Sint8 *scopes,
1414 mday         1.1  			 Sint16 lifetime) 
1415                   {
1416                     Sint32 len;
1417                     Sint16 str_len;
1418                     Sint8 *bptr;
1419                   
1420                   
1421                     /* this is always a new request */
1422                     memset( _pr_buf, 0x00, LSLP_MTU);
1423                     _pr_buf_len = 0;
1424                     _xid++ ;
1425                   
1426                     memset(_msg_buf, 0x00, LSLP_MTU);
1427                     bptr = _msg_buf;
1428                     _LSLP_SETVERSION(bptr, LSLP_PROTO_VER);
1429                     _LSLP_SETFUNCTION(bptr, LSLP_SRVREG);
1430                     /* we don't know the length yet */
1431                     _LSLP_SETXID(bptr, _xid);
1432                     _LSLP_SETLAN(bptr, LSLP_EN_US);
1433                     bptr += (len =  _LSLP_HDRLEN(bptr) ) ;
1434                   	
1435 mday         1.1    /* construct a url-entry  */
1436                   
1437                     _LSLP_SETSHORT(bptr, lifetime, 1);
1438                     _LSLP_SETSHORT(bptr, (str_len = (strlen(url) + 1)), 3);
1439                     len += (5 + str_len );
1440                     if(len + 1 < LSLP_MTU ) {
1441                       memcpy(bptr + 5, url, str_len);
1442                       bptr += (5 + str_len);
1443                       /* no auth blocks for now  */
1444                       _LSLP_SETBYTE(bptr, 0x00, 0);
1445                       bptr++;
1446                       len++;
1447                       /* stuff the service type  */
1448                       str_len = strlen(service_type) + 1;
1449                       if(len + 2 + str_len < LSLP_MTU) {
1450                         _LSLP_SETSHORT(bptr, str_len, 0);
1451                         memcpy(bptr + 2, service_type, str_len);
1452                         bptr += (2 + str_len);
1453                         len += (2 + str_len);
1454                         /* stuff the scope list if there is one */
1455                         if(scopes == NULL)
1456 mday         1.1  	str_len = 0;
1457                         else 
1458                   	str_len = strlen(scopes) + 1;	  
1459                         if(str_len == 1)
1460                   	str_len = 0;
1461                         if(len + 2 + str_len < LSLP_MTU) {
1462                   	_LSLP_SETSHORT(bptr, str_len, 0);
1463                   	if(str_len) 
1464                   	  memcpy(bptr + 2, scopes, str_len);
1465                   	      
1466                   	len += (2 + str_len);
1467                   	bptr += (2 + str_len);
1468                   	/* stuff the attribute string if there is one */
1469                   	if(attributes == NULL)
1470                   	  str_len = 0;
1471                   	else
1472                   	  str_len = strlen(attributes) + 1;
1473                   	if(str_len == 1)
1474                   	  str_len = 0;
1475                   	if(len + 2 + str_len < LSLP_MTU) {
1476                   	  _LSLP_SETSHORT(bptr, str_len, 0);
1477 mday         1.1  	  if(str_len)
1478                   	    memcpy(bptr + 2, attributes, str_len);
1479                   		  
1480                   	  len += ( 2 + str_len);
1481                   	  bptr += (2 + str_len);
1482                   
1483                   	  /* no attribute auths for now */
1484                   	  if(len + 1 < LSLP_MTU) {
1485                   	    _LSLP_SETBYTE(bptr, 0x00, 0);
1486                   	  }
1487                   	  len += 1;
1488                   	  /* set the length field in the header */
1489                   	  _LSLP_SETLENGTH( _msg_buf, len );
1490 mday         1.4  	  int retries = _retries;
1491                   	  while( --retries ) {
1492                   	    if(true == send_rcv_udp(  )) {
1493                   	      if(LSLP_SRVACK == _LSLP_GETFUNCTION( _rcv_buf )) {
1494                   		if(0x0000 == _LSLP_GETSHORT( _rcv_buf, (_LSLP_HDRLEN( _rcv_buf )))) {
1495                   		  memset(_msg_buf, 0x00, LSLP_MTU);
1496                   		  return(true); 
1497                   		}
1498 mday         1.1  	      }
1499 mday         1.4  	    } // received a response 
1500                   	  } // retrying the unicast 
1501 mday         1.1  	} /* attribute string fits into buffer */
1502                         } /* scope string fits into buffer  */
1503                       } /* service type fits into buffer  */
1504                     } /* url fits into buffer  */
1505                     memset( _msg_buf, 0x00, LSLP_MTU);
1506                     return(false);
1507                   }
1508                   
1509                   
1510                   
1511                   Boolean slp_client::send_rcv_udp( void )
1512                   {
1513                     SOCKET sock;
1514                     struct sockaddr_in target, local;
1515                     Boolean ccode = false;
1516                     if(INVALID_SOCKET != (sock = socket(AF_INET, SOCK_DGRAM, 0))) {
1517                       int err = 1;
1518 chuck        1.15 #ifndef PEGASUS_OS_OS400
1519 mday         1.1      setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&err, sizeof(err) );
1520 chuck        1.15 #else
1521                       setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&err, sizeof(err) );
1522                   #endif
1523 mday         1.1  
1524                       local.sin_family = AF_INET;
1525                       local.sin_port = 0;
1526                       local.sin_addr.s_addr = _local_addr;
1527 mike         1.6      if(SOCKET_ERROR != bind(sock, SOCKADDR_CAST&local, sizeof(local))) {
1528 mday         1.1        int bcast = ( (_LSLP_GETFLAGS(_msg_buf)) & LSLP_FLAGS_MCAST) ? 1 : 0 ;
1529                         if(bcast) {
1530 chuck        1.15 	if( (SOCKET_ERROR ==  _LSLP_SET_TTL(sock, _ttl) )  ||
1531                   #ifndef PEGASUS_OS_OS400  
1532 mday         1.1  	    (SOCKET_ERROR == setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (const Sint8 *)&bcast, sizeof(bcast)))) {
1533 chuck        1.15 #else
1534                   	    (SOCKET_ERROR == setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&bcast, sizeof(bcast)))) {
1535                   #endif
1536 mday         1.1  	  _LSLP_CLOSESOCKET(sock);
1537                   	  return(false);
1538                   	}
1539                   	if(_local_addr != INADDR_ANY ) {
1540                   	  struct sockaddr_in ma;
1541                   	  memset(&ma, 0x00, sizeof(ma));
1542                   	  ma.sin_addr.s_addr = _local_addr;
1543 chuck        1.15 #ifndef PEGASUS_OS_OS400
1544 mday         1.1  	  if( (SOCKET_ERROR == setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&ma, sizeof(struct sockaddr_in))) ) {
1545 chuck        1.15 #else
1546                   	  if( (SOCKET_ERROR == setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (char *)&ma, sizeof(struct sockaddr_in))) ) {
1547                   #endif
1548 mday         1.1  	    _LSLP_CLOSESOCKET(sock);
1549                   	    return(false);
1550                   	  }
1551                   	}
1552                         }
1553                         target.sin_family = AF_INET;
1554 mday         1.4        target.sin_port = _target_port;
1555 mday         1.1        target.sin_addr.s_addr = _target_addr;
1556                         if(SOCKET_ERROR == (err = sendto(sock, 
1557                   				       _msg_buf, 
1558                   				       _LSLP_GETLENGTH(_msg_buf), 
1559                   				       0, 
1560 mike         1.6  				       SOCKADDR_CAST&target, sizeof(target) ))) {
1561 mday         1.1  	_LSLP_CLOSESOCKET(sock);
1562                   	return(false);
1563                         } /* oops - error sending data */
1564 mday         1.4  
1565                   
1566                         while ( 0 < service_listener( sock ) ) { ccode = true; }
1567                   
1568 mday         1.2      } // bound the socket 
1569 mday         1.1      _LSLP_CLOSESOCKET(sock);
1570                     } /*  got the socket */
1571                     return(ccode);
1572                   }
1573                        
1574 mday         1.2  // must be called regularly to process responses 
1575                   
1576                   Sint32 slp_client::service_listener(void)
1577                   {
1578                     return service_listener((SOCKET) 0);
1579                   }
1580                   
1581                   
1582                   Sint32 slp_client::service_listener_wait(time_t wait, SOCKET extra_sock, Boolean one_only)
1583                   {
1584                     Sint32 rcv = 0;
1585                     time_t now;
1586                     time_t start = time(NULL);
1587                   
1588                     while( time(&now) && ((now - wait ) <= start )  ) {
1589                       rcv += service_listener(extra_sock);
1590                       if(rcv > 0)
1591                         if(one_only == true)
1592                   	return(rcv);
1593 mike         1.5  
1594                   #ifdef PEGASUS_OS_TRU64
1595                       usleep(10 * 1000);
1596                   #else
1597 mday         1.2      _LSLP_SLEEP(10);
1598 mike         1.5  #endif
1599 mday         1.2    }
1600                     rcv += service_listener(extra_sock);
1601                     return(rcv);
1602                   }
1603                   
1604                   Sint32 slp_client::service_listener(SOCKET extra_sock )
1605                   {
1606                   
1607 mday         1.4    struct timeval tv; 
1608 mday         1.2    fd_set fds;
1609                     FD_ZERO(&fds);
1610 mday         1.4    if(_rcv_sock != INVALID_SOCKET) {
1611                       FD_SET(_rcv_sock, &fds);
1612                     }
1613 mday         1.2    if(extra_sock)
1614                       FD_SET( extra_sock, &fds);
1615                     Sint32 err;
1616                     do { 
1617 mday         1.4      tv.tv_sec = _tv.tv_sec;
1618                       tv.tv_usec = _tv.tv_usec;
1619 mday         1.2      err = select(_rcv_sock > extra_sock ? _rcv_sock + 1: extra_sock + 1, &fds, NULL, NULL, &tv); 
1620                     } while ( (err < 0 )&& (errno == EINTR)) ;
1621                     if( 0 < err ) {
1622                       struct sockaddr_in remote;
1623 mday         1.4  
1624 keith.petley 1.17 #if defined(PEGASUS_OS_HPUX) || defined(PEGASUS_OS_TRU64) || ( defined PEGASUS_OS_SOLARIS && defined SUNOS_5_6)
1625 mday         1.2      int size = sizeof(remote);
1626 karl         1.3  #else
1627 mday         1.4      socklen_t size = sizeof(remote);
1628 karl         1.3  #endif
1629 mday         1.4  
1630                       if(extra_sock && FD_ISSET(extra_sock, &fds) )
1631 mike         1.6        err = recvfrom(extra_sock, _rcv_buf, LSLP_MTU, 0, SOCKADDR_CAST&remote, &size);
1632 mday         1.4      if(_rcv_sock != INVALID_SOCKET) {
1633                         if(FD_ISSET(_rcv_sock, &fds)) 
1634 mike         1.6  	err = recvfrom(_rcv_sock, _rcv_buf, LSLP_MTU, 0, SOCKADDR_CAST&remote, &size);
1635 mday         1.2      }
1636 mday         1.4  
1637                       if(err && err != SOCKET_ERROR)
1638                         decode_msg( &remote );
1639                     } 
1640                     if (err == SOCKET_ERROR) {
1641                       // our interfaces could be disconnected or we could be a laptop that 
1642                       // just got pulled from the network, etc. 
1643                       _LSLP_CLOSESOCKET(_rcv_sock );
1644                       if( 0 < slp_get_local_interfaces( & _local_addr_list ) ) {
1645                         if(_rcv_sock != INVALID_SOCKET)
1646                         	_rcv_sock = slp_open_listen_sock( );
1647 mday         1.2      }
1648 mday         1.4    } 
1649 mday         1.2    return(err);
1650                   }
1651                   
1652 kumpf        1.10 int slp_client::srv_reg_all( const Sint8 *url,
1653                   			     const Sint8 *attributes,
1654                   			     const Sint8 *service_type,
1655                   			     const Sint8 *scopes,
1656 mday         1.1  			     Sint16 lifetime)
1657                   {
1658                   
1659                     assert(url != NULL && attributes != NULL && service_type != NULL && scopes != NULL);
1660                     if(url == NULL || attributes == NULL || service_type == NULL || scopes == NULL )
1661                       return(0);
1662                       
1663                     // see if we have built a cache of directory agents 
1664                     if(  0 == das.count() ) {
1665 mday         1.4      // we don't know of any directory agents - see if we need to do active da discovery
1666                       if( ((time(NULL)) - _last_da_cycle ) > (60 * 5) )
1667                         find_das(NULL, scopes) ;
1668 mday         1.1    }
1669                   
1670 mday         1.4    // keep track of how many times we register
1671 mday         1.1    int registrations = 0;
1672 mday         1.4  
1673                     // save target and convergence parameters 
1674 mday         1.1    Uint32 target_addr_save = _target_addr;
1675                     int convergence_save = _convergence;
1676                     _convergence = 0;
1677                   
1678 mday         1.4    // if there are das, unicast a srvreg to each da
1679                   
1680                     if( 0 < das.count() ) {
1681                   
1682                       da_list *da = das.next(NULL);
1683                       while( da != NULL ) {
1684                         set_target_addr(da->remote);
1685                         if( true == srv_reg( url, attributes, service_type, scopes, lifetime) )
1686                   	registrations++;
1687                         da = das.next(da);;
1688                       }
1689 mday         1.1    }
1690                   
1691 mday         1.4    // restore parameters 
1692 mday         1.1    _convergence = convergence_save;
1693                     _target_addr = target_addr_save;
1694                     
1695 mday         1.4  
1696                     // if we have registered with any das, act like a service agent and cache our
1697                     // own registration. This provides a failsafe in case the DA is not available 
1698                     srv_reg_local(url, attributes, service_type, scopes, lifetime);
1699                     registrations++;
1700                     
1701 mday         1.1    return(registrations);
1702                   }
1703                   
1704 mday         1.4  
1705 kumpf        1.10 void  slp_client::srv_reg_local ( const Sint8 *url,
1706                   				  const Sint8 *attributes, 
1707                   				  const Sint8 *service_type, 
1708                   				  const Sint8 *scopes, 
1709 mday         1.4  				  Sint16 lifetime) 
1710                   {
1711                     reg_list *reg = NULL;
1712                     // first see if the reg already exists. if it does, just update the lifetime
1713                     if ( NULL != (reg = regs.reference(url))) {
1714                       reg->lifetime = lifetime + time(NULL);
1715                     } else {  // new reg 
1716                       reg = new reg_list(url, attributes, service_type, scopes, (lifetime + time(NULL)));
1717                       regs.insert(reg);
1718                     }
1719                     return;
1720                   }
1721                   
1722                   Boolean slp_client::slp_previous_responder(Sint8 *pr_list)
1723                   {
1724                   
1725                     Sint8 *a, *s = NULL;
1726                     Uint32 addr, *list_addr;
1727                     if(pr_list == NULL || 0 == strlen(pr_list))
1728                       return(false);
1729                   
1730 mday         1.4    a = _LSLP_STRTOK(pr_list, ",", &s);
1731                     while(NULL != a ) {
1732                       if(INADDR_NONE != (addr = inet_addr(a))) {
1733                         list_addr = _local_addr_list;
1734                         while( INADDR_ANY != *list_addr ) {
1735                   	if(*list_addr == addr)
1736                   	  return(true);
1737                   	list_addr++;
1738                         }
1739                       }
1740                       a = _LSLP_STRTOK(NULL, ",", &s);
1741                     }
1742                     return(false);
1743                   }
1744 mday         1.1  
1745                   PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2