Fawkes API  Fawkes Development Version
qa_avahi_resolver.cpp
1 
2 /***************************************************************************
3  * qa_avahi_resolver.cpp - QA for AvahiResolver
4  *
5  * Created: Fri May 11 12:31:35 2007
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 /// @cond QA
25 
26 #include <netcomm/dns-sd/avahi_thread.h>
27 #include <netcomm/dns-sd/avahi_resolver_handler.h>
28 
29 #include <core/exception.h>
30 #include <utils/system/signal.h>
31 #include <utils/system/argparser.h>
32 
33 #include <cstdio>
34 #include <cstdlib>
35 #include <arpa/inet.h>
36 #include <netinet/in.h>
37 
38 using namespace fawkes;
39 
40 class QAAvahiResolverMain : public SignalHandler, public AvahiResolverHandler
41 {
42  public:
43  QAAvahiResolverMain(ArgumentParser *argp)
44  {
45  this->argp = argp;
46  at = new AvahiThread();
47  wait_for_name = false;
48  wait_for_addr = false;
49  }
50 
51  ~QAAvahiResolverMain()
52  {
53  delete at;
54  }
55 
56  virtual void handle_signal(int signum)
57  {
58  at->cancel();
59  }
60 
61  void run()
62  {
63  printf("Starting AvahiThread\n");
64  at->start();
65 
66  printf("Waiting until AvahiThread has been initialized\n");
67  at->wait_initialized();
68 
69  wait_for_name = argp->has_arg("n");
70  wait_for_addr = argp->has_arg("a");
71 
72  const char *tmp;
73  if ( (tmp = argp->arg("n")) != NULL ) {
74  printf("Calling name resolver\n");
75  at->resolve_name(tmp, this);
76  }
77 
78  if ( (tmp = argp->arg("a")) != NULL ) {
79  printf("Calling address resolver\n");
80  struct sockaddr_in saddr;
81  if ( inet_pton(AF_INET, tmp, &(saddr.sin_addr)) >= 0 ) {
82  at->resolve_address((struct sockaddr *)&saddr, sizeof(saddr), this);
83  }
84  }
85 
86  printf("Waiting for thread\n");
87  at->join();
88  }
89 
90  virtual void resolved_name(char *name, struct sockaddr *addr, socklen_t addrlen)
91  {
92  char addrp[INET_ADDRSTRLEN];
93  struct sockaddr_in *in_addr = (struct sockaddr_in *)addr;
94  if ( inet_ntop(AF_INET, &(in_addr->sin_addr), addrp, sizeof(addrp)) ) {
95  printf("'%s' resolved to '%s'\n", name, addrp);
96  } else {
97  printf("'%s' resolved, but could not transform address to presentation form\n", name);
98  }
99 
100  free(name);
101  free(addr);
102 
103  wait_for_name = false;
104  if ( ! wait_for_name && ! wait_for_addr ) at->cancel();
105  }
106 
107 
108  virtual void resolved_address(struct sockaddr_in *addr, socklen_t addrlen, char *name)
109  {
110  char addrp[INET_ADDRSTRLEN];
111  struct sockaddr_in *in_addr = (struct sockaddr_in *)addr;
112  if ( inet_ntop(AF_INET, &(in_addr->sin_addr), addrp, sizeof(addrp)) ) {
113  printf("Address %s resolved to %s\n", addrp, name);
114  } else {
115  printf("Unknown address resolved to '%s'\n", name);
116  }
117 
118  free(addr);
119  free(name);
120 
121  wait_for_addr = false;
122  if ( ! wait_for_name && ! wait_for_addr ) at->cancel();
123  }
124 
125  virtual void name_resolution_failed(char *name)
126  {
127  printf("Could not resolve '%s'\n", name);
128  free(name);
129 
130  wait_for_name = false;
131  if ( ! wait_for_name && ! wait_for_addr ) at->cancel();
132  }
133 
134 
135  virtual void address_resolution_failed(struct sockaddr_in *addr, socklen_t addrlen)
136  {
137  free(addr);
138 
139  wait_for_addr = false;
140  if ( ! wait_for_name && ! wait_for_addr ) at->cancel();
141  }
142 
143 
144  private:
145  AvahiThread *at;
146  ArgumentParser *argp;
147 
148  bool wait_for_name;
149  bool wait_for_addr;
150 };
151 
152 int
153 main(int argc, char **argv)
154 {
155  ArgumentParser *argp = new ArgumentParser(argc, argv, "n:a:");
156 
157  if ( ! argp->has_arg("n") && ! argp->has_arg("a") ) {
158  printf("Usage: %s [-n name] [-a address]\n\n", argv[0]);
159  delete argp;
160  return -1;
161  }
162 
163  try {
164  QAAvahiResolverMain m(argp);
166 
167  m.run();
168 
169  } catch (Exception &e) {
170  e.print_trace();
171  }
172 
174  delete argp;
175 }
176 
177 /// @endcond
static void finalize()
Finalize (and free) the SignalManager instance, this does NOT implicitly delete the signal handlers...
Definition: signal.cpp:98
Fawkes library namespace.
Interface for signal handling.
Definition: signal.h:35
Parse command line arguments.
Definition: argparser.h:66
Avahi resolver handler interface.
Base class for exceptions in Fawkes.
Definition: exception.h:36
static SignalHandler * register_handler(int signum, SignalHandler *handler)
Register a SignalHandler for a signal.
Definition: signal.cpp:116
Avahi main thread.
Definition: avahi_thread.h:54
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:619
bool has_arg(const char *argn)
Check if argument has been supplied.
Definition: argparser.cpp:169