service.cpp

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
00027 #include <sys/types.h>
00028 #include <arpa/inet.h>
00029 #include <netinet/in.h>
00030 #include <inttypes.h>
00031 #include <cstddef>
00032 #include <cstring>
00033 #include <cstdlib>
00034
00035 namespace fawkes {
00036 #if 0 /* just to make Emacs auto-indent happy */
00037 }
00038 #endif
00039 
00040 /** @class NetworkService <netcomm/service_discovery/service.h>
00041  * Representation of a service announced or found via service
00042  * discovery (i.e. mDNS/DNS-SD via Avahi).
00043  * This class is used in the C++ wrapper to talk about services.
00044  *
00045  * @ingroup NetComm
00046  * @author Tim Niemueller
00047  */
00048 
00049 /** Constructor.
00050  * This constructor sets all parameters.
00051  * @param name name of service
00052  * @param type type of service
00053  * @param domain domain of service
00054  * @param host host of service
00055  * @param port port of service
00056  */
00057 NetworkService::NetworkService(const char         *name,
00058                                const char         *type,
00059                                const char         *domain,
00060                                const char         *host,
00061                                unsigned short int  port)
00062 {
00063   _name   = strdup(name);
00064   _type   = strdup(type);
00065   _domain = strdup(domain);
00066   _host   = strdup(host);
00067   _port   = port;
00068
00069   _addr = NULL;
00070   _addr_size = 0;
00071 }
00072
00073 
00074 /** Constructor.
00075  * This constructor sets all parameters.
00076  * @param name name of service
00077  * @param type type of service
00078  * @param domain domain of service
00079  * @param host host of service
00080  * @param port port of service
00081  * @param addr address of the service
00082  * @param addr_size size in bytes of addr parameter
00083  * @param txt list of TXT records
00084  */
00085 NetworkService::NetworkService(const char         *name,
00086                                const char         *type,
00087                                const char         *domain,
00088                                const char         *host,
00089                                unsigned short int  port,
00090                                const struct sockaddr *addr,
00091                                const socklen_t     addr_size,
00092                                std::list<std::string> &txt)
00093
00094 {
00095   _name   = strdup(name);
00096   _type   = strdup(type);
00097   _domain = strdup(domain);
00098   _host   = strdup(host);
00099   _port   = port;
00100
00101   _addr = (struct sockaddr *)malloc(addr_size);
00102   memcpy(_addr, addr, addr_size);
00103   _addr_size = addr_size;
00104   list = txt;
00105 }
00106
00107 
00108 /** Constructor.
00109  * This constructor sets all parameters. Host and domain are the
00110  * default values, which means local host name in domain .local
00111  * (if not set otherwise in Avahi system configuration).
00112  * @param name name of service
00113  * @param type type of service
00114  * @param port port of service
00115  */
00116 NetworkService::NetworkService(const char         *name,
00117                                const char         *type,
00118                                unsigned short int  port)
00119 {
00120   _name   = strdup(name);
00121   _type   = strdup(type);
00122   _domain = NULL;
00123   _host   = NULL;
00124   _port   = port;
00125
00126   _addr = NULL;
00127   _addr_size = 0;
00128 }
00129
00130 
00131 /** Constructor.
00132  * This constructor sets all parameters. Host and domain are the
00133  * default values, which means local host name in domain .local
00134  * (if not set otherwise in Avahi system configuration).
00135  * This specific constructor allows the usage of a "%h" token in
00136  * the name, which is replaced with the short hostname.
00137  * @param nnresolver network name resolver to get the host from for
00138  * the replacement of a %h token.
00139  * @param name name of service
00140  * @param type type of service
00141  * @param port port of service
00142  */
00143 NetworkService::NetworkService(NetworkNameResolver *nnresolver,
00144                                const char         *name,
00145                                const char         *type,
00146                                unsigned short int  port)
00147 {
00148   std::string s = name;
00149   std::string::size_type hpos = s.find("%h");
00150   if (nnresolver && (hpos != std::string::npos)) {
00151     s.replace(hpos, 2, nnresolver->short_hostname());
00152   }
00153   _name   = strdup(s.c_str());
00154   _type   = strdup(type);
00155   _domain = NULL;
00156   _host   = NULL;
00157   _port   = port;
00158
00159   _addr = NULL;
00160   _addr_size = 0;
00161 }
00162 
00163 /** Constructor.
00164  * This constructor sets all parameters.
00165  * @param name name of service
00166  * @param type type of service
00167  * @param domain domain of service
00168  */
00169 NetworkService::NetworkService(const char         *name,
00170                                const char         *type,
00171                                const char         *domain)
00172 {
00173   _name   = strdup(name);
00174   _type   = strdup(type);
00175   _domain = strdup(domain);
00176
00177   _host   = NULL;
00178   _port   = 0;
00179   _addr = NULL;
00180   _addr_size = 0;
00181 }
00182
00183 
00184 /** Destructor. */
00185 NetworkService::~NetworkService()
00186 {
00187   if ( _name   != NULL)  free( _name );
00188   if ( _type   != NULL)  free( _type );
00189   if ( _domain != NULL)  free( _domain );
00190   if ( _host   != NULL)  free( _host );
00191   if ( _addr   != NULL)  free( _addr );
00192 }
00193
00194 
00195 /** Copy constructor (pointer).
00196  * Create a copy of given NetworkService.
00197  * @param s network service to copy from
00198  */
00199 NetworkService::NetworkService(const NetworkService *s)
00200 {
00201   _name = strdup(s->_name);
00202   _type = strdup(s->_type);
00203   _port = s->_port;
00204   if ( s->_domain != NULL ) {
00205     _domain = strdup(s->_domain);
00206   } else {
00207     _domain = NULL;
00208   }
00209   if ( s->_host != NULL ) {
00210     _host = strdup(s->_host);
00211   } else {
00212     _host = NULL;
00213   }
00214
00215   _addr = NULL;
00216   _addr_size = 0;
00217
00218   list = s->list;
00219 }
00220
00221 
00222 /** Copy constructor (reference).
00223  * Create a copy of given NetworkService.
00224  * @param s network service to copy from
00225  */
00226 NetworkService::NetworkService(const NetworkService &s)
00227 {
00228   _name = strdup(s._name);
00229   _type = strdup(s._type);
00230   _port = s._port;
00231   if ( s._domain != NULL ) {
00232     _domain = strdup(s._domain);
00233   } else {
00234     _domain = NULL;
00235   }
00236   if ( s._host != NULL ) {
00237     _host = strdup(s._host);
00238   } else {
00239     _host = NULL;
00240   }
00241
00242   _addr = NULL;
00243   _addr_size = 0;
00244
00245   list = s.list;
00246 }
00247
00248 
00249 /** Add a TXT record.
00250  * @param txt TXT record to add, must be a "key=value" string.
00251  */
00252 void
00253 NetworkService::add_txt(const char *txt)
00254 {
00255   list.push_back(txt);
00256 }
00257
00258 
00259 /** Set TXT records all at once.
00260  * @param txtlist list of TXT records
00261  */
00262 void
00263 NetworkService::set_txt(std::list<std::string> &txtlist)
00264 {
00265   list = txtlist;
00266 }
00267
00268 
00269 /** Set name of service.
00270  * @param new_name new name
00271  */
00272 void
00273 NetworkService::set_name(const char *new_name)
00274 {
00275   free( _name );
00276   _name = strdup(new_name);
00277 }
00278
00279 
00280 /** Get name of service.
00281  * @return name of service
00282  */
00283 const char *
00284 NetworkService::name() const
00285 {
00286   return _name;
00287 }
00288
00289 
00290 /** Get type of service.
00291  * @return type of service
00292  */
00293 const char *
00294 NetworkService::type() const
00295 {
00296   return _type;
00297 }
00298
00299 
00300 /** Get domain of service.
00301  * @return domain of service
00302  */
00303 const char *
00304 NetworkService::domain() const
00305 {
00306   return _domain;
00307 }
00308
00309 
00310 /** Get host of service.
00311  * @return host of service
00312  */
00313 const char *
00314 NetworkService::host() const
00315 {
00316   return _host;
00317 }
00318
00319 
00320 /** Get port of service.
00321  * @return port of service
00322  */
00323 unsigned short int
00324 NetworkService::port() const
00325 {
00326   return _port;
00327 }
00328
00329 
00330 /** Get IP address of entry as string.
00331  * @return IP address as string
00332  * @exception NullPointerException thrown if the address has not been set
00333  */
00334 std::string
00335 NetworkService::addr_string() const
00336 {
00337   char ipaddr[INET_ADDRSTRLEN];
00338   struct sockaddr_in *saddr = (struct sockaddr_in *)_addr;
00339   return std::string(inet_ntop(AF_INET, &(saddr->sin_addr), ipaddr, sizeof(ipaddr)));
00340 }
00341
00342 
00343 /** Get TXT record list of service.
00344  * @return TXT record list of service
00345  */
00346 const std::list<std::string> &
00347 NetworkService::txt() const
00348 {
00349   return list;
00350 }
00351
00352 
00353 /** Equal operator for NetworkService reference.
00354  * @param s reference of service to compare to.
00355  * @return true, if the services are the same (same name and type), false otherwise
00356  */
00357 bool
00358 NetworkService::operator==(const NetworkService &s) const
00359 {
00360   return ( (strcmp(_name, s._name) == 0) &&
00361            (strcmp(_type, s._type) == 0) );
00362 }
00363
00364 
00365 /** Equal operator for NetworkService pointer.
00366  * @param s pointer to service to compare to.
00367  * @return true, if the services are the same (same name and type), false otherwise
00368  */
00369 bool
00370 NetworkService::operator==(const NetworkService *s) const
00371 {
00372   return ( (strcmp(_name, s->_name) == 0) &&
00373            (strcmp(_type, s->_type) == 0) );
00374 }
00375
00376 
00377 /** Less than operator.
00378  * @param s reference of service to compare to
00379  * @return true, if either the type is less than (according to strcmp) or if types
00380  * are equal if the service name is less than the given service's name.
00381  */
00382 bool
00383 NetworkService::operator<(const NetworkService &s) const
00384 {
00385   int typediff = strcmp(_type, s._type);
00386   if ( typediff == 0 ) {
00387     return (strcmp(_name, s._name) < 0);
00388   } else {
00389     return (typediff < 0);
00390   }
00391 }
00392
00393 } // end namespace fawkes