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
37using namespace fawkes;
38
39class QAAvahiResolverMain : public SignalHandler, public AvahiResolverHandler
40{
41public:
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
150private:
151 AvahiThread * at;
152 ArgumentParser *argp;
153
154 bool wait_for_name;
155 bool wait_for_addr;
156};
157
158int
159main(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);
171 SignalManager::register_handler(SIGINT, &m);
172
173 m.run();
174
175 } catch (Exception &e) {
176 e.print_trace();
177 }
178
179 SignalManager::finalize();
180 delete argp;
181}
182
183/// @endcond
Parse command line arguments.
Definition: argparser.h:64
bool has_arg(const char *argn)
Check if argument has been supplied.
Definition: argparser.cpp:165
Avahi resolver handler interface.
Avahi main thread.
Definition: avahi_thread.h:55
Base class for exceptions in Fawkes.
Definition: exception.h:36
void print_trace() noexcept
Prints trace to stderr.
Definition: exception.cpp:601
Interface for signal handling.
Definition: signal.h:36
Fawkes library namespace.