00001
00012
00013
00014
00015
00016 #ifdef HAVE_CONFIG_H
00017 #include <config.h>
00018 #endif
00019
00020 #include <iostream>
00021 #include <time.h>
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <assert.h>
00025
00026 #include <avahi-client/client.h>
00027 #include <avahi-client/publish.h>
00028
00029 #include <avahi-common/alternative.h>
00030 #include <avahi-common/simple-watch.h>
00031 #include <avahi-common/malloc.h>
00032 #include <avahi-common/error.h>
00033 #include <avahi-common/timeval.h>
00034
00035 static AvahiEntryGroup *group = NULL;
00036 static AvahiSimplePoll *simple_poll = NULL;
00037 static char *name = NULL;
00038
00039 static void create_services(AvahiClient *c);
00040
00041 static void entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, AVAHI_GCC_UNUSED void *userdata) {
00042 assert(g == group || group == NULL);
00043 group = g;
00044
00045
00046
00047 switch (state) {
00048 case AVAHI_ENTRY_GROUP_ESTABLISHED :
00049 std::cout << "Entry group established" << std::endl;
00050
00051 fprintf(stderr, "Service '%s' successfully established.\n", name);
00052 break;
00053
00054 case AVAHI_ENTRY_GROUP_COLLISION : {
00055 char *n;
00056 std::cout << "Entry group collision" << std::endl;
00057
00058
00059
00060 n = avahi_alternative_service_name(name);
00061 avahi_free(name);
00062 name = n;
00063
00064 fprintf(stderr, "Service name collision, renaming service to '%s'\n", name);
00065
00066
00067 create_services(avahi_entry_group_get_client(g));
00068 break;
00069 }
00070
00071 case AVAHI_ENTRY_GROUP_FAILURE :
00072
00073 std::cout << "Entry group failure" << std::endl;
00074 fprintf(stderr, "Entry group failure: %s\n", avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g))));
00075
00076
00077 avahi_simple_poll_quit(simple_poll);
00078 break;
00079
00080 case AVAHI_ENTRY_GROUP_UNCOMMITED:
00081 std::cout << "Entry group uncommitted" << std::endl;
00082 break;
00083 case AVAHI_ENTRY_GROUP_REGISTERING:
00084 std::cout << "Entry group registering" << std::endl;
00085 break;
00086 }
00087 }
00088
00089 static void create_services(AvahiClient *c) {
00090 char *n, r[128];
00091 int ret;
00092 assert(c);
00093
00094
00095
00096
00097 if (!group)
00098 if (!(group = avahi_entry_group_new(c, entry_group_callback, NULL))) {
00099 fprintf(stderr, "avahi_entry_group_new() failed: %s\n", avahi_strerror(avahi_client_errno(c)));
00100 goto fail;
00101 }
00102
00103
00104
00105
00106 if (avahi_entry_group_is_empty(group)) {
00107 fprintf(stderr, "Adding service '%s'\n", name);
00108
00109
00110 snprintf(r, sizeof(r), "random=%i", rand());
00111
00112
00113
00114
00115
00116
00117
00118 if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, static_cast<AvahiPublishFlags>(0), name, "_ipp._tcp", NULL, NULL, 651, "test=blah", r, NULL)) < 0) {
00119
00120 if (ret == AVAHI_ERR_COLLISION)
00121 goto collision;
00122
00123 fprintf(stderr, "Failed to add _ipp._tcp service: %s\n", avahi_strerror(ret));
00124 goto fail;
00125 }
00126
00127
00128 if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, static_cast<AvahiPublishFlags>(0), name, "_printer._tcp", NULL, NULL, 515, NULL)) < 0) {
00129
00130 if (ret == AVAHI_ERR_COLLISION)
00131 goto collision;
00132
00133 fprintf(stderr, "Failed to add _printer._tcp service: %s\n", avahi_strerror(ret));
00134 goto fail;
00135 }
00136
00137
00138 if ((ret = avahi_entry_group_add_service_subtype(group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, static_cast<AvahiPublishFlags>(0), name, "_printer._tcp", NULL, "_magic._sub._printer._tcp") < 0)) {
00139 fprintf(stderr, "Failed to add subtype _magic._sub._printer._tcp: %s\n", avahi_strerror(ret));
00140 goto fail;
00141 }
00142
00143
00144 if ((ret = avahi_entry_group_commit(group)) < 0) {
00145 fprintf(stderr, "Failed to commit entry group: %s\n", avahi_strerror(ret));
00146 goto fail;
00147 }
00148 }
00149
00150 return;
00151
00152 collision:
00153
00154
00155
00156 n = avahi_alternative_service_name(name);
00157 avahi_free(name);
00158 name = n;
00159
00160 fprintf(stderr, "Service name collision, renaming service to '%s'\n", name);
00161
00162 avahi_entry_group_reset(group);
00163
00164 create_services(c);
00165 return;
00166
00167 fail:
00168 avahi_simple_poll_quit(simple_poll);
00169 }
00170
00171 static void client_callback(AvahiClient *c, AvahiClientState state, AVAHI_GCC_UNUSED void * userdata) {
00172 assert(c);
00173
00174
00175
00176 switch (state) {
00177 case AVAHI_CLIENT_S_RUNNING:
00178
00179
00180
00181 create_services(c);
00182 break;
00183
00184 case AVAHI_CLIENT_FAILURE:
00185
00186 fprintf(stderr, "Client failure: %s\n", avahi_strerror(avahi_client_errno(c)));
00187 avahi_simple_poll_quit(simple_poll);
00188
00189 break;
00190
00191 case AVAHI_CLIENT_S_COLLISION:
00192
00193
00194
00195
00196
00197 case AVAHI_CLIENT_S_REGISTERING:
00198
00199
00200
00201
00202
00203 if (group)
00204 avahi_entry_group_reset(group);
00205
00206 break;
00207
00208 case AVAHI_CLIENT_CONNECTING:
00209 ;
00210 }
00211 }
00212
00213 static void modify_callback(AVAHI_GCC_UNUSED AvahiTimeout *e, void *userdata) {
00214 AvahiClient *client = static_cast<AvahiClient*>(userdata);
00215
00216 fprintf(stderr, "Doing some weird modification\n");
00217
00218 avahi_free(name);
00219 name = avahi_strdup("Modified MegaPrinter");
00220
00221
00222
00223 if (avahi_client_get_state(client) == AVAHI_CLIENT_S_RUNNING) {
00224
00225
00226 if (group)
00227 avahi_entry_group_reset(group);
00228
00229
00230 create_services(client);
00231 }
00232 }
00233
00234
00235
00236
00237
00238 int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char **argv) {
00239
00240 AvahiClient *client = NULL;
00241 int error;
00242 int ret = 1;
00243 struct timeval tv;
00244
00245
00246 if (!(simple_poll = avahi_simple_poll_new())) {
00247 fprintf(stderr, "Failed to create simple poll object.\n");
00248 goto fail;
00249 }
00250
00251 name = avahi_strdup("MegaPrinter");
00252
00253
00254 client = avahi_client_new(avahi_simple_poll_get(simple_poll), static_cast<AvahiClientFlags>(0), client_callback, NULL, &error);
00255
00256
00257 if (!client) {
00258 fprintf(stderr, "Failed to create client: %s\n", avahi_strerror(error));
00259 goto fail;
00260 }
00261
00262
00263 avahi_simple_poll_get(simple_poll)->timeout_new(
00264 avahi_simple_poll_get(simple_poll),
00265 avahi_elapse_time(&tv, 1000*10, 0),
00266 modify_callback,
00267 client);
00268
00269
00270 avahi_simple_poll_loop(simple_poll);
00271
00272 ret = 0;
00273
00274 fail:
00275
00276
00277
00278 if (client)
00279 avahi_client_free(client);
00280
00281 if (simple_poll)
00282 avahi_simple_poll_free(simple_poll);
00283
00284 avahi_free(name);
00285
00286 return ret;
00287 }