1/* $Id$ */
2
3/***
4  This file is part of avahi.
5
6  avahi is free software; you can redistribute it and/or modify it
7  under the terms of the GNU Lesser General Public License as
8  published by the Free Software Foundation; either version 2.1 of the
9  License, or (at your option) any later version.
10
11  avahi is distributed in the hope that it will be useful, but WITHOUT
12  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
14  Public License for more details.
15
16  You should have received a copy of the GNU Lesser General Public
17  License along with avahi; if not, write to the Free Software
18  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  USA.
20***/
21
22#ifdef HAVE_CONFIG_H
23#include <config.h>
24#endif
25
26#include <stdlib.h>
27#include <unistd.h>
28#include <stdio.h>
29#include <assert.h>
30
31#include <sys/types.h>
32#include <sys/socket.h>
33#include <netinet/in.h>
34#include <arpa/inet.h>
35
36#include <avahi-common/alternative.h>
37#include <avahi-common/malloc.h>
38#include <avahi-common/simple-watch.h>
39#include <avahi-common/timeval.h>
40
41#include <avahi-core/core.h>
42#include <avahi-core/log.h>
43#include <avahi-core/lookup.h>
44#include <avahi-core/publish.h>
45
46static char *name = NULL;
47static AvahiSEntryGroup *group = NULL;
48static int try = 0;
49static AvahiServer *avahi = NULL;
50static const AvahiPoll *poll_api;
51
52static void dump_line(const char *text, AVAHI_GCC_UNUSED void* userdata) {
53    printf("%s\n", text);
54}
55
56static void dump_timeout_callback(AvahiTimeout *timeout, AVAHI_GCC_UNUSED void* userdata) {
57    struct timeval tv;
58
59    avahi_server_dump(avahi, dump_line, NULL);
60
61    avahi_elapse_time(&tv, 5000, 0);
62    poll_api->timeout_update(timeout, &tv);
63}
64
65static void entry_group_callback(AvahiServer *s, AvahiSEntryGroup *g, AvahiEntryGroupState state, void* userdata);
66
67static void create_service(const char *t) {
68    char *n;
69
70    assert(t || name);
71
72    n = t ? avahi_strdup(t) : avahi_alternative_service_name(name);
73    avahi_free(name);
74    name = n;
75
76    if (group)
77        avahi_s_entry_group_reset(group);
78    else
79        group = avahi_s_entry_group_new(avahi, entry_group_callback, NULL);
80
81    avahi_server_add_service(avahi, group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, name, "_http._tcp", NULL, NULL, 80, "foo", NULL);
82    avahi_s_entry_group_commit(group);
83
84    try++;
85}
86
87static void rename_timeout_callback(AvahiTimeout *timeout, AVAHI_GCC_UNUSED void *userdata) {
88    struct timeval tv;
89
90    if (access("flag", F_OK) == 0) {
91        create_service("New - Bonjour Service Name");
92        return;
93    }
94
95    avahi_elapse_time(&tv, 5000, 0);
96    poll_api->timeout_update(timeout, &tv);
97}
98
99static void entry_group_callback(AVAHI_GCC_UNUSED AvahiServer *s, AVAHI_GCC_UNUSED AvahiSEntryGroup *g, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void* userdata) {
100    if (state == AVAHI_ENTRY_GROUP_COLLISION)
101        create_service(NULL);
102    else if (state == AVAHI_ENTRY_GROUP_ESTABLISHED) {
103        avahi_log_debug("ESTABLISHED !!!!");
104        try = 0;
105    }
106}
107
108static void server_callback(AvahiServer *s, AvahiServerState state, AVAHI_GCC_UNUSED void* userdata) {
109    avahi_log_debug("server state: %i", state);
110
111    if (state == AVAHI_SERVER_RUNNING) {
112        avahi_server_dump(avahi, dump_line, NULL);
113    } else if (state == AVAHI_SERVER_COLLISION) {
114        char *n;
115
116        n = avahi_alternative_host_name(avahi_server_get_host_name(s));
117        avahi_log_warn("Host name conflict, retrying with <%s>", n);
118        avahi_server_set_host_name(s, n);
119        avahi_free(n);
120
121    }
122}
123
124int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) {
125    int error;
126    AvahiSimplePoll *simple_poll;
127    struct timeval tv;
128    struct AvahiServerConfig config;
129
130    simple_poll = avahi_simple_poll_new();
131    poll_api = avahi_simple_poll_get(simple_poll);
132
133    avahi_server_config_init(&config);
134    config.publish_workstation = 0;
135    config.use_ipv6 = 0;
136    config.publish_domain = 0;
137    config.publish_hinfo = 0;
138    avahi = avahi_server_new(poll_api, &config, server_callback, NULL, &error);
139    avahi_server_config_free(&config);
140
141    avahi_elapse_time(&tv, 5000, 0);
142    poll_api->timeout_new(poll_api, &tv, dump_timeout_callback, avahi);
143
144    avahi_elapse_time(&tv, 5000, 0);
145    poll_api->timeout_new(poll_api, &tv, rename_timeout_callback, avahi);
146
147    /* Evil, but the conformace test requires that*/
148    create_service("gurke");
149
150
151    avahi_simple_poll_loop(simple_poll);
152
153    if (group)
154        avahi_s_entry_group_free(group);
155    avahi_server_free(avahi);
156
157    avahi_simple_poll_free(simple_poll);
158
159    return 0;
160}
161