Fawkes API  Fawkes Development Version
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
service.cpp
1 
2 /***************************************************************************
3  * service.cpp - Network service representation
4  *
5  * Generated: Tue Nov 07 18:02:23 2006
6  * Copyright 2006-2007 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <netcomm/service_discovery/service.h>
25 #include <netcomm/utils/resolver.h>
26 #include <core/exceptions/system.h>
27 
28 #include <sys/types.h>
29 #include <arpa/inet.h>
30 #include <netinet/in.h>
31 #include <inttypes.h>
32 #include <cstddef>
33 #include <cstring>
34 #include <cstdlib>
35 #include <cstdarg>
36 #include <cstdio>
37 
38 namespace fawkes {
39 #if 0 /* just to make Emacs auto-indent happy */
40 }
41 #endif
42 
43 /** @class NetworkService <netcomm/service_discovery/service.h>
44  * Representation of a service announced or found via service
45  * discovery (i.e. mDNS/DNS-SD via Avahi).
46  * This class is used in the C++ wrapper to talk about services.
47  *
48  * @ingroup NetComm
49  * @author Tim Niemueller
50  */
51 
52 /** Constructor.
53  * This constructor sets all parameters.
54  * @param name name of service
55  * @param type type of service
56  * @param domain domain of service
57  * @param host host of service
58  * @param port port of service
59  */
60 NetworkService::NetworkService(const char *name,
61  const char *type,
62  const char *domain,
63  const char *host,
64  unsigned short int port)
65 {
66  _name = strdup(name);
67  _type = strdup(type);
68  _domain = strdup(domain);
69  _host = strdup(host);
70  _port = port;
71 
72  _modified_name = NULL;
73 
74  _addr = NULL;
75  _addr_size = 0;
76 }
77 
78 
79 /** Constructor.
80  * This constructor sets all parameters.
81  * @param name name of service
82  * @param type type of service
83  * @param domain domain of service
84  * @param host host of service
85  * @param port port of service
86  * @param addr address of the service
87  * @param addr_size size in bytes of addr parameter
88  * @param txt list of TXT records
89  */
90 NetworkService::NetworkService(const char *name,
91  const char *type,
92  const char *domain,
93  const char *host,
94  unsigned short int port,
95  const struct sockaddr *addr,
96  const socklen_t addr_size,
97  std::list<std::string> &txt)
98 
99 {
100  _name = strdup(name);
101  _type = strdup(type);
102  _domain = strdup(domain);
103  _host = strdup(host);
104  _port = port;
105 
106  _modified_name = NULL;
107 
108  _addr = (struct sockaddr *)malloc(addr_size);
109  memcpy(_addr, addr, addr_size);
110  _addr_size = addr_size;
111  list = txt;
112 }
113 
114 
115 /** Constructor.
116  * This constructor sets all parameters. Host and domain are the
117  * default values, which means local host name in domain .local
118  * (if not set otherwise in Avahi system configuration).
119  * @param name name of service
120  * @param type type of service
121  * @param port port of service
122  */
123 NetworkService::NetworkService(const char *name,
124  const char *type,
125  unsigned short int port)
126 {
127  _name = strdup(name);
128  _type = strdup(type);
129  _domain = NULL;
130  _host = NULL;
131  _port = port;
132 
133  _modified_name = NULL;
134 
135  _addr = NULL;
136  _addr_size = 0;
137 }
138 
139 
140 /** Constructor.
141  * This constructor sets all parameters. Host and domain are the
142  * default values, which means local host name in domain .local
143  * (if not set otherwise in Avahi system configuration).
144  * This specific constructor allows the usage of a "%h" token in
145  * the name, which is replaced with the short hostname.
146  * @param nnresolver network name resolver to get the host from for
147  * the replacement of a %h token.
148  * @param name name of service
149  * @param type type of service
150  * @param port port of service
151  */
152 NetworkService::NetworkService(NetworkNameResolver *nnresolver,
153  const char *name,
154  const char *type,
155  unsigned short int port)
156 {
157  std::string s = name;
158  std::string::size_type hpos = s.find("%h");
159  if (nnresolver && (hpos != std::string::npos)) {
160  s.replace(hpos, 2, nnresolver->short_hostname());
161  }
162  _name = strdup(s.c_str());
163  _type = strdup(type);
164  _domain = NULL;
165  _host = NULL;
166  _port = port;
167 
168  _modified_name = NULL;
169 
170  _addr = NULL;
171  _addr_size = 0;
172 }
173 
174 /** Constructor.
175  * This constructor sets all parameters.
176  * @param name name of service
177  * @param type type of service
178  * @param domain domain of service
179  */
180 NetworkService::NetworkService(const char *name,
181  const char *type,
182  const char *domain)
183 {
184  _name = strdup(name);
185  _type = strdup(type);
186  _domain = strdup(domain);
187 
188  _modified_name = NULL;
189 
190  _host = NULL;
191  _port = 0;
192  _addr = NULL;
193  _addr_size = 0;
194 }
195 
196 
197 /** Destructor. */
198 NetworkService::~NetworkService()
199 {
200  if ( _name != NULL) free( _name );
201  if ( _type != NULL) free( _type );
202  if ( _domain != NULL) free( _domain );
203  if ( _host != NULL) free( _host );
204  if ( _addr != NULL) free( _addr );
205  if ( _modified_name != NULL) free( _modified_name );
206 }
207 
208 
209 /** Copy constructor (pointer).
210  * Create a copy of given NetworkService.
211  * @param s network service to copy from
212  */
213 NetworkService::NetworkService(const NetworkService *s)
214 {
215  _name = strdup(s->_name);
216  _type = strdup(s->_type);
217  _port = s->_port;
218  if ( s->_domain != NULL ) {
219  _domain = strdup(s->_domain);
220  } else {
221  _domain = NULL;
222  }
223  if ( s->_host != NULL ) {
224  _host = strdup(s->_host);
225  } else {
226  _host = NULL;
227  }
228 
229  _modified_name = NULL;
230  if (s->_modified_name != NULL) {
231  _modified_name = strdup(s->_modified_name);
232  }
233 
234  _addr = NULL;
235  _addr_size = 0;
236 
237  list = s->list;
238 }
239 
240 
241 /** Copy constructor (reference).
242  * Create a copy of given NetworkService.
243  * @param s network service to copy from
244  */
245 NetworkService::NetworkService(const NetworkService &s)
246 {
247  _name = strdup(s._name);
248  _type = strdup(s._type);
249  _port = s._port;
250  if ( s._domain != NULL ) {
251  _domain = strdup(s._domain);
252  } else {
253  _domain = NULL;
254  }
255  if ( s._host != NULL ) {
256  _host = strdup(s._host);
257  } else {
258  _host = NULL;
259  }
260 
261  _modified_name = NULL;
262  if (s._modified_name != NULL) {
263  _modified_name = strdup(s._modified_name);
264  }
265 
266  _addr = NULL;
267  _addr_size = 0;
268 
269  list = s.list;
270 }
271 
272 
273 /** Add a TXT record.
274  * @param format format for TXT record to add, must be a "key=value" string,
275  * takes the same arguments as sprintf.
276  */
277 void
278 NetworkService::add_txt(const char *format, ...)
279 {
280  va_list arg;
281  va_start(arg, format);
282  char *tmp;
283  if (vasprintf(&tmp, format, arg) == -1) {
284  throw OutOfMemoryException("Cannot add txt record, no memory");
285  }
286  list.push_back(tmp);
287  free(tmp);
288  va_end(arg);
289 }
290 
291 
292 /** Set TXT records all at once.
293  * @param txtlist list of TXT records
294  */
295 void
296 NetworkService::set_txt(std::list<std::string> &txtlist)
297 {
298  list = txtlist;
299 }
300 
301 
302 /** Set name of service.
303  * @param new_name new name
304  */
305 void
306 NetworkService::set_name(const char *new_name)
307 {
308  free( _name );
309  _name = strdup(new_name);
310 }
311 
312 
313 /** Get name of service.
314  * @return name of service
315  */
316 const char *
317 NetworkService::name() const
318 {
319  return _name;
320 }
321 
322 
323 /** Set modified name of service.
324  * The modified name is the original name with a suffix that has been added
325  * to resolve a name collision.
326  * @param new_name new name
327  */
328 void
329 NetworkService::set_modified_name(const char *new_name) const
330 {
331  if (_modified_name) free(_modified_name);
332  _modified_name = strdup(new_name);
333 }
334 
335 
336 /** Get modified name of service.
337  * The modified name is the original name with a suffix that has been added
338  * to resolve a name collision.
339  * @return modified name of service, this may be NULL if the name has not
340  * been modified
341  */
342 const char *
343 NetworkService::modified_name() const
344 {
345  return _modified_name;
346 }
347 
348 
349 /** Get type of service.
350  * @return type of service
351  */
352 const char *
353 NetworkService::type() const
354 {
355  return _type;
356 }
357 
358 
359 /** Get domain of service.
360  * @return domain of service
361  */
362 const char *
363 NetworkService::domain() const
364 {
365  return _domain;
366 }
367 
368 
369 /** Get host of service.
370  * @return host of service
371  */
372 const char *
373 NetworkService::host() const
374 {
375  return _host;
376 }
377 
378 
379 /** Get port of service.
380  * @return port of service
381  */
382 unsigned short int
383 NetworkService::port() const
384 {
385  return _port;
386 }
387 
388 
389 /** Get IP address of entry as string.
390  * @return IP address as string
391  * @exception NullPointerException thrown if the address has not been set
392  */
393 std::string
394 NetworkService::addr_string() const
395 {
396  char ipaddr[INET_ADDRSTRLEN];
397  struct sockaddr_in *saddr = (struct sockaddr_in *)_addr;
398  return std::string(inet_ntop(AF_INET, &(saddr->sin_addr), ipaddr, sizeof(ipaddr)));
399 }
400 
401 
402 /** Get TXT record list of service.
403  * @return TXT record list of service
404  */
405 const std::list<std::string> &
406 NetworkService::txt() const
407 {
408  return list;
409 }
410 
411 
412 /** Equal operator for NetworkService reference.
413  * @param s reference of service to compare to.
414  * @return true, if the services are the same (same name and type), false otherwise
415  */
416 bool
417 NetworkService::operator==(const NetworkService &s) const
418 {
419  return ( (strcmp(_name, s._name) == 0) &&
420  (strcmp(_type, s._type) == 0) );
421 }
422 
423 
424 /** Equal operator for NetworkService pointer.
425  * @param s pointer to service to compare to.
426  * @return true, if the services are the same (same name and type), false otherwise
427  */
428 bool
429 NetworkService::operator==(const NetworkService *s) const
430 {
431  return ( (strcmp(_name, s->_name) == 0) &&
432  (strcmp(_type, s->_type) == 0) );
433 }
434 
435 
436 /** Less than operator.
437  * @param s reference of service to compare to
438  * @return true, if either the type is less than (according to strcmp) or if types
439  * are equal if the service name is less than the given service's name.
440  */
441 bool
442 NetworkService::operator<(const NetworkService &s) const
443 {
444  int typediff = strcmp(_type, s._type);
445  if ( typediff == 0 ) {
446  return (strcmp(_name, s._name) < 0);
447  } else {
448  return (typediff < 0);
449  }
450 }
451 
452 } // end namespace fawkes
const char * short_hostname()
Get short hostname.
Definition: resolver.cpp:384
Representation of a service announced or found via service discovery (i.e.
Definition: service.h:37
Network name and address resolver.
Definition: resolver.h:48
System ran out of memory and desired operation could not be fulfilled.
Definition: system.h:32