Fawkes API
Fawkes Development Version
|
00001 00002 /*************************************************************************** 00003 * service.cpp - Network service representation 00004 * 00005 * Generated: Tue Nov 07 18:02:23 2006 00006 * Copyright 2006-2007 Tim Niemueller [www.niemueller.de] 00007 * 00008 ****************************************************************************/ 00009 00010 /* This program is free software; you can redistribute it and/or modify 00011 * it under the terms of the GNU General Public License as published by 00012 * the Free Software Foundation; either version 2 of the License, or 00013 * (at your option) any later version. A runtime exception applies to 00014 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Library General Public License for more details. 00020 * 00021 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00022 */ 00023 00024 #include <netcomm/service_discovery/service.h> 00025 #include <netcomm/utils/resolver.h> 00026 #include <core/exceptions/system.h> 00027 00028 #include <sys/types.h> 00029 #include <arpa/inet.h> 00030 #include <netinet/in.h> 00031 #include <inttypes.h> 00032 #include <cstddef> 00033 #include <cstring> 00034 #include <cstdlib> 00035 #include <cstdarg> 00036 #include <cstdio> 00037 00038 namespace fawkes { 00039 #if 0 /* just to make Emacs auto-indent happy */ 00040 } 00041 #endif 00042 00043 /** @class NetworkService <netcomm/service_discovery/service.h> 00044 * Representation of a service announced or found via service 00045 * discovery (i.e. mDNS/DNS-SD via Avahi). 00046 * This class is used in the C++ wrapper to talk about services. 00047 * 00048 * @ingroup NetComm 00049 * @author Tim Niemueller 00050 */ 00051 00052 /** Constructor. 00053 * This constructor sets all parameters. 00054 * @param name name of service 00055 * @param type type of service 00056 * @param domain domain of service 00057 * @param host host of service 00058 * @param port port of service 00059 */ 00060 NetworkService::NetworkService(const char *name, 00061 const char *type, 00062 const char *domain, 00063 const char *host, 00064 unsigned short int port) 00065 { 00066 _name = strdup(name); 00067 _type = strdup(type); 00068 _domain = strdup(domain); 00069 _host = strdup(host); 00070 _port = port; 00071 00072 _modified_name = NULL; 00073 00074 _addr = NULL; 00075 _addr_size = 0; 00076 } 00077 00078 00079 /** Constructor. 00080 * This constructor sets all parameters. 00081 * @param name name of service 00082 * @param type type of service 00083 * @param domain domain of service 00084 * @param host host of service 00085 * @param port port of service 00086 * @param addr address of the service 00087 * @param addr_size size in bytes of addr parameter 00088 * @param txt list of TXT records 00089 */ 00090 NetworkService::NetworkService(const char *name, 00091 const char *type, 00092 const char *domain, 00093 const char *host, 00094 unsigned short int port, 00095 const struct sockaddr *addr, 00096 const socklen_t addr_size, 00097 std::list<std::string> &txt) 00098 00099 { 00100 _name = strdup(name); 00101 _type = strdup(type); 00102 _domain = strdup(domain); 00103 _host = strdup(host); 00104 _port = port; 00105 00106 _modified_name = NULL; 00107 00108 _addr = (struct sockaddr *)malloc(addr_size); 00109 memcpy(_addr, addr, addr_size); 00110 _addr_size = addr_size; 00111 list = txt; 00112 } 00113 00114 00115 /** Constructor. 00116 * This constructor sets all parameters. Host and domain are the 00117 * default values, which means local host name in domain .local 00118 * (if not set otherwise in Avahi system configuration). 00119 * @param name name of service 00120 * @param type type of service 00121 * @param port port of service 00122 */ 00123 NetworkService::NetworkService(const char *name, 00124 const char *type, 00125 unsigned short int port) 00126 { 00127 _name = strdup(name); 00128 _type = strdup(type); 00129 _domain = NULL; 00130 _host = NULL; 00131 _port = port; 00132 00133 _modified_name = NULL; 00134 00135 _addr = NULL; 00136 _addr_size = 0; 00137 } 00138 00139 00140 /** Constructor. 00141 * This constructor sets all parameters. Host and domain are the 00142 * default values, which means local host name in domain .local 00143 * (if not set otherwise in Avahi system configuration). 00144 * This specific constructor allows the usage of a "%h" token in 00145 * the name, which is replaced with the short hostname. 00146 * @param nnresolver network name resolver to get the host from for 00147 * the replacement of a %h token. 00148 * @param name name of service 00149 * @param type type of service 00150 * @param port port of service 00151 */ 00152 NetworkService::NetworkService(NetworkNameResolver *nnresolver, 00153 const char *name, 00154 const char *type, 00155 unsigned short int port) 00156 { 00157 std::string s = name; 00158 std::string::size_type hpos = s.find("%h"); 00159 if (nnresolver && (hpos != std::string::npos)) { 00160 s.replace(hpos, 2, nnresolver->short_hostname()); 00161 } 00162 _name = strdup(s.c_str()); 00163 _type = strdup(type); 00164 _domain = NULL; 00165 _host = NULL; 00166 _port = port; 00167 00168 _modified_name = NULL; 00169 00170 _addr = NULL; 00171 _addr_size = 0; 00172 } 00173 00174 /** Constructor. 00175 * This constructor sets all parameters. 00176 * @param name name of service 00177 * @param type type of service 00178 * @param domain domain of service 00179 */ 00180 NetworkService::NetworkService(const char *name, 00181 const char *type, 00182 const char *domain) 00183 { 00184 _name = strdup(name); 00185 _type = strdup(type); 00186 _domain = strdup(domain); 00187 00188 _modified_name = NULL; 00189 00190 _host = NULL; 00191 _port = 0; 00192 _addr = NULL; 00193 _addr_size = 0; 00194 } 00195 00196 00197 /** Destructor. */ 00198 NetworkService::~NetworkService() 00199 { 00200 if ( _name != NULL) free( _name ); 00201 if ( _type != NULL) free( _type ); 00202 if ( _domain != NULL) free( _domain ); 00203 if ( _host != NULL) free( _host ); 00204 if ( _addr != NULL) free( _addr ); 00205 if ( _modified_name != NULL) free( _modified_name ); 00206 } 00207 00208 00209 /** Copy constructor (pointer). 00210 * Create a copy of given NetworkService. 00211 * @param s network service to copy from 00212 */ 00213 NetworkService::NetworkService(const NetworkService *s) 00214 { 00215 _name = strdup(s->_name); 00216 _type = strdup(s->_type); 00217 _port = s->_port; 00218 if ( s->_domain != NULL ) { 00219 _domain = strdup(s->_domain); 00220 } else { 00221 _domain = NULL; 00222 } 00223 if ( s->_host != NULL ) { 00224 _host = strdup(s->_host); 00225 } else { 00226 _host = NULL; 00227 } 00228 00229 _modified_name = NULL; 00230 if (s->_modified_name != NULL) { 00231 _modified_name = strdup(s->_modified_name); 00232 } 00233 00234 _addr = NULL; 00235 _addr_size = 0; 00236 00237 list = s->list; 00238 } 00239 00240 00241 /** Copy constructor (reference). 00242 * Create a copy of given NetworkService. 00243 * @param s network service to copy from 00244 */ 00245 NetworkService::NetworkService(const NetworkService &s) 00246 { 00247 _name = strdup(s._name); 00248 _type = strdup(s._type); 00249 _port = s._port; 00250 if ( s._domain != NULL ) { 00251 _domain = strdup(s._domain); 00252 } else { 00253 _domain = NULL; 00254 } 00255 if ( s._host != NULL ) { 00256 _host = strdup(s._host); 00257 } else { 00258 _host = NULL; 00259 } 00260 00261 _modified_name = NULL; 00262 if (s._modified_name != NULL) { 00263 _modified_name = strdup(s._modified_name); 00264 } 00265 00266 _addr = NULL; 00267 _addr_size = 0; 00268 00269 list = s.list; 00270 } 00271 00272 00273 /** Add a TXT record. 00274 * @param format format for TXT record to add, must be a "key=value" string, 00275 * takes the same arguments as sprintf. 00276 */ 00277 void 00278 NetworkService::add_txt(const char *format, ...) 00279 { 00280 va_list arg; 00281 va_start(arg, format); 00282 char *tmp; 00283 if (vasprintf(&tmp, format, arg) == -1) { 00284 throw OutOfMemoryException("Cannot add txt record, no memory"); 00285 } 00286 list.push_back(tmp); 00287 free(tmp); 00288 va_end(arg); 00289 } 00290 00291 00292 /** Set TXT records all at once. 00293 * @param txtlist list of TXT records 00294 */ 00295 void 00296 NetworkService::set_txt(std::list<std::string> &txtlist) 00297 { 00298 list = txtlist; 00299 } 00300 00301 00302 /** Set name of service. 00303 * @param new_name new name 00304 */ 00305 void 00306 NetworkService::set_name(const char *new_name) 00307 { 00308 free( _name ); 00309 _name = strdup(new_name); 00310 } 00311 00312 00313 /** Get name of service. 00314 * @return name of service 00315 */ 00316 const char * 00317 NetworkService::name() const 00318 { 00319 return _name; 00320 } 00321 00322 00323 /** Set modified name of service. 00324 * The modified name is the original name with a suffix that has been added 00325 * to resolve a name collision. 00326 * @param new_name new name 00327 */ 00328 void 00329 NetworkService::set_modified_name(const char *new_name) const 00330 { 00331 if (_modified_name) free(_modified_name); 00332 _modified_name = strdup(new_name); 00333 } 00334 00335 00336 /** Get modified name of service. 00337 * The modified name is the original name with a suffix that has been added 00338 * to resolve a name collision. 00339 * @return modified name of service, this may be NULL if the name has not 00340 * been modified 00341 */ 00342 const char * 00343 NetworkService::modified_name() const 00344 { 00345 return _modified_name; 00346 } 00347 00348 00349 /** Get type of service. 00350 * @return type of service 00351 */ 00352 const char * 00353 NetworkService::type() const 00354 { 00355 return _type; 00356 } 00357 00358 00359 /** Get domain of service. 00360 * @return domain of service 00361 */ 00362 const char * 00363 NetworkService::domain() const 00364 { 00365 return _domain; 00366 } 00367 00368 00369 /** Get host of service. 00370 * @return host of service 00371 */ 00372 const char * 00373 NetworkService::host() const 00374 { 00375 return _host; 00376 } 00377 00378 00379 /** Get port of service. 00380 * @return port of service 00381 */ 00382 unsigned short int 00383 NetworkService::port() const 00384 { 00385 return _port; 00386 } 00387 00388 00389 /** Get IP address of entry as string. 00390 * @return IP address as string 00391 * @exception NullPointerException thrown if the address has not been set 00392 */ 00393 std::string 00394 NetworkService::addr_string() const 00395 { 00396 char ipaddr[INET_ADDRSTRLEN]; 00397 struct sockaddr_in *saddr = (struct sockaddr_in *)_addr; 00398 return std::string(inet_ntop(AF_INET, &(saddr->sin_addr), ipaddr, sizeof(ipaddr))); 00399 } 00400 00401 00402 /** Get TXT record list of service. 00403 * @return TXT record list of service 00404 */ 00405 const std::list<std::string> & 00406 NetworkService::txt() const 00407 { 00408 return list; 00409 } 00410 00411 00412 /** Equal operator for NetworkService reference. 00413 * @param s reference of service to compare to. 00414 * @return true, if the services are the same (same name and type), false otherwise 00415 */ 00416 bool 00417 NetworkService::operator==(const NetworkService &s) const 00418 { 00419 return ( (strcmp(_name, s._name) == 0) && 00420 (strcmp(_type, s._type) == 0) ); 00421 } 00422 00423 00424 /** Equal operator for NetworkService pointer. 00425 * @param s pointer to service to compare to. 00426 * @return true, if the services are the same (same name and type), false otherwise 00427 */ 00428 bool 00429 NetworkService::operator==(const NetworkService *s) const 00430 { 00431 return ( (strcmp(_name, s->_name) == 0) && 00432 (strcmp(_type, s->_type) == 0) ); 00433 } 00434 00435 00436 /** Less than operator. 00437 * @param s reference of service to compare to 00438 * @return true, if either the type is less than (according to strcmp) or if types 00439 * are equal if the service name is less than the given service's name. 00440 */ 00441 bool 00442 NetworkService::operator<(const NetworkService &s) const 00443 { 00444 int typediff = strcmp(_type, s._type); 00445 if ( typediff == 0 ) { 00446 return (strcmp(_name, s._name) < 0); 00447 } else { 00448 return (typediff < 0); 00449 } 00450 } 00451 00452 } // end namespace fawkes