6 #include <avahi-client/client.h>
7 #include <avahi-client/publish.h>
9 #include <avahi-common/alternative.h>
10 #include <avahi-common/simple-watch.h>
11 #include <avahi-common/malloc.h>
12 #include <avahi-common/error.h>
13 #include <avahi-common/timeval.h>
15 #include <libvirt/libvirt.h>
20 unsigned int domainid
;
21 AvahiEntryGroup
*group
;
25 typedef struct list_el domu
;
27 domu
* domus
= NULL
; /* list of domains */
28 unsigned int domu_count
= 0;
29 static AvahiSimplePoll
*simple_poll
= NULL
;
32 static void entry_group_callback(AvahiEntryGroup
*g
, AvahiEntryGroupState state
, AVAHI_GCC_UNUSED
void *userdata
) {
33 /* Called whenever the entry group state changes */
36 case AVAHI_ENTRY_GROUP_ESTABLISHED
:
37 /* The entry group has been established successfully */
38 //fprintf(stderr, "Service '%s' successfully established.\n", name);
41 case AVAHI_ENTRY_GROUP_COLLISION
: {
44 /* A service name collision with a remote service
45 * happened. Let's pick a new name */
46 //n = avahi_alternative_service_name(name);
50 // fprintf(stderr, "Service name collision, renaming service to '%s'\n", name);
52 /* And recreate the services */
53 //create_services(avahi_entry_group_get_client(g));
57 case AVAHI_ENTRY_GROUP_FAILURE
:
59 fprintf(stderr
, "Entry group failure: %s\n", avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g
))));
61 /* Some kind of failure happened while we were registering our services */
62 avahi_simple_poll_quit(simple_poll
);
65 case AVAHI_ENTRY_GROUP_UNCOMMITED
:
66 case AVAHI_ENTRY_GROUP_REGISTERING
:
71 void create_services(AvahiClient
*c
) {
72 virConnectPtr conn
= virConnectOpenReadOnly(NULL
);
75 int maxid
= virConnectNumOfDomains(conn
);
76 if (maxid
> 1) { /* ignore dom0 */
77 int *ids
= (int *) malloc(sizeof(int) * maxid
);
78 if ((maxid
= virConnectListDomains(conn
, &ids
[0], maxid
)) < 0) {
82 unsigned int domu_count_new
= (maxid
- 1);
83 domu
* domus_old
= domus
;
84 domus
= (domu
*) malloc(sizeof(domu
) * domu_count_new
);
85 for (i
= 0; i
< domu_count_new
; i
++) {
87 domus
[i
].group
= NULL
;
88 domus
[i
].domainid
= ids
[i
+1];
91 for (j
= 0; j
< domu_count
; j
++) {
92 if (ids
[i
+1] == domus_old
[j
].domainid
) {
93 domus
[i
].group
= domus_old
[j
].group
;
94 domus_old
[j
].keep
= 1;
97 if (i
> domu_count
|| domus
[i
].group
== NULL
) {
98 virDomainPtr thisDomain
;
99 thisDomain
= virDomainLookupByID(conn
, ids
[i
+1]);
100 domus
[i
].group
= avahi_entry_group_new(c
, entry_group_callback
, NULL
);
101 avahi_entry_group_add_service(domus
[i
].group
, AVAHI_IF_UNSPEC
, AVAHI_PROTO_UNSPEC
, 0, virDomainGetName(thisDomain
), "_domu._tcp", NULL
, NULL
, 651, "test=blah", NULL
, NULL
);
102 avahi_entry_group_commit(domus
[i
].group
);
106 for (i
= 0; i
< domu_count
; i
++) {
107 if (domus_old
[i
].keep
== 0 && domus_old
[i
].group
!= NULL
) {
108 avahi_entry_group_free(domus_old
[i
].group
);
113 domu_count
= domu_count_new
;
117 virConnectClose(conn
);
121 static void client_callback(AvahiClient
*c
, AvahiClientState state
, AVAHI_GCC_UNUSED
void * userdata
) {
124 /* Called whenever the client or server state changes */
127 case AVAHI_CLIENT_S_RUNNING
:
129 /* The server has startup successfully and registered its host
130 * name on the network, so it's time to create our services */
134 case AVAHI_CLIENT_FAILURE
:
136 fprintf(stderr
, "Client failure: %s\n", avahi_strerror(avahi_client_errno(c
)));
137 avahi_simple_poll_quit(simple_poll
);
141 case AVAHI_CLIENT_S_COLLISION
:
143 /* Let's drop our registered services. When the server is back
144 * in AVAHI_SERVER_RUNNING state we will register them
145 * again with the new host name. */
147 case AVAHI_CLIENT_S_REGISTERING
:
149 /* The server records are now being established. This
150 * might be caused by a host name change. We need to wait
151 * for our own records to register until the host name is
152 * properly esatblished. */
155 avahi_entry_group_reset(group);*/
159 case AVAHI_CLIENT_CONNECTING
:
166 static void modify_callback(AvahiTimeout
*e
, void *userdata
) {
168 AvahiClient
*client
= userdata
;
170 // fprintf(stderr, "Doing some weird modification\n");
172 /* If the server is currently running, we need to remove our
173 * service and create it anew */
174 if (avahi_client_get_state(client
) == AVAHI_CLIENT_S_RUNNING
) {
175 /* And create them again with the new name */
176 create_services(client
);
178 avahi_simple_poll_get(simple_poll
)->timeout_update(e
, avahi_elapse_time(&tv
, 1000*POLL
, 0));
181 int main(AVAHI_GCC_UNUSED
int argc
, AVAHI_GCC_UNUSED
char*argv
[]) {
182 AvahiClient
*client
= NULL
;
186 /* Allocate main loop object */
187 if (!(simple_poll
= avahi_simple_poll_new())) {
188 fprintf(stderr
, "Failed to create simple poll object.\n");
192 /* Allocate a new client */
193 client
= avahi_client_new(avahi_simple_poll_get(simple_poll
), 0, client_callback
, NULL
, &error
);
195 /* Check wether creating the client object succeeded */
197 fprintf(stderr
, "Failed to create client: %s\n", avahi_strerror(error
));
201 /* After 10s do some weird modification to the service */
202 avahi_simple_poll_get(simple_poll
)->timeout_new(
203 avahi_simple_poll_get(simple_poll
),
204 avahi_elapse_time(&tv
, 1000*POLL
, 0),
208 /* Run the main loop */
209 avahi_simple_poll_loop(simple_poll
);
218 avahi_client_free(client
);
221 avahi_simple_poll_free(simple_poll
);