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