void avahi_init_proc_title(int argc, char **argv) { #if !defined(HAVE_SETPROCTITLE) && defined(__linux__) unsigned i; char **new_environ, *endptr; /* This code is really really ugly. We make some memory layout * assumptions and reuse the environment array as memory to store * our process title in */ for (i = 0; environ[i]; i++); endptr = i ? environ[i-1] + strlen(environ[i-1]) : argv[argc-1] + strlen(argv[argc-1]); argv_buffer = argv; argv_size = endptr - argv_buffer[0]; /* Make a copy of environ */ new_environ = avahi_malloc(sizeof(char*) * (i + 1)); for (i = 0; environ[i]; i++) new_environ[i] = avahi_strdup(environ[i]); new_environ[i] = NULL; environ = new_environ; #endif }
void NetworkServicesProviderAvahi::removeServiceInfo(ServiceInfo* i) { ASSERT(i); NetworkServicesProviderAvahi* p = i->provider; char* id; id = (char*) avahi_malloc(strlen(i->name) + strlen(i->type) + strlen(i->domain) + 4); sprintf(id, "%s.%s.%s.", i->name, i->type, i->domain); p->removeServiceDescription(id); AVAHI_LLIST_REMOVE(ServiceInfo, info, m_services, i); if (i->resolver) avahi_service_resolver_free(i->resolver); avahi_free(i->name); avahi_free(i->type); avahi_free(i->domain); avahi_free(i); }
static void inotify_callback(AvahiWatch *watch, int fd, AVAHI_GCC_UNUSED AvahiWatchEvent event, AVAHI_GCC_UNUSED void *userdata) { char* buffer; int n = 0; assert(fd == inotify_fd); assert(watch); ioctl(inotify_fd, FIONREAD, &n); if (n <= 0) n = 128; buffer = avahi_malloc(n); if (read(inotify_fd, buffer, n) < 0 ) { avahi_free(buffer); avahi_log_error("Failed to read inotify event: %s", avahi_strerror(errno)); return; } avahi_free(buffer); avahi_log_info("Files changed, reloading."); reload_config(); }
void NetworkServicesProviderAvahi::serviceBrowserCallback( AVAHI_GCC_UNUSED AvahiServiceBrowser* b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char* name, const char* type, const char* domain, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, void* userdata) { NetworkServicesProviderAvahi* p = static_cast<NetworkServicesProviderAvahi*>(userdata); ASSERT(b); ASSERT(p); switch (event) { case AVAHI_BROWSER_NEW: { ServiceInfo* info; printServiceLine('+', interface, protocol, name, type, domain); if ((info = p->findService(interface, protocol, name, type, domain))) { char* id; NetworkServiceDescription* desc; if (!(info->notify)) return; id = (char*) avahi_malloc(strlen(name) + strlen(type) + strlen(domain) + 4); sprintf(id, "%s.%s.%s.", name, type, domain); desc = p->getServiceDescriptionById(String::fromUTF8(id)); if (desc) { desc->setOnline(true); p->notifyNetworkServiceChanged(desc); } avahi_free(id); info->notify = false; return; } p->addServiceInfo(interface, protocol, name, type, domain); break; } case AVAHI_BROWSER_REMOVE: { ServiceInfo* info; if (!(info = p->findService(interface, protocol, name, type, domain))) return; if (info->notify) { p->removeServiceInfo(info); info->notify = false; } printServiceLine('-', interface, protocol, name, type, domain); break; } case AVAHI_BROWSER_FAILURE: LOG_ERROR("service_browser failed: %s\n", avahi_strerror(avahi_client_errno(p->m_avahiClient))); break; case AVAHI_BROWSER_CACHE_EXHAUSTED: break; case AVAHI_BROWSER_ALL_FOR_NOW: p->m_allForNow--; p->checkTerminate(); break; } }
void NetworkServicesProviderAvahi::serviceResolverCallback( AVAHI_GCC_UNUSED AvahiServiceResolver* r, AVAHI_GCC_UNUSED AvahiIfIndex interface, AVAHI_GCC_UNUSED AvahiProtocol protocol, AvahiResolverEvent event, const char* name, const char* type, const char* domain, const char* hostName, const AvahiAddress* a, AVAHI_GCC_UNUSED uint16_t port, AvahiStringList* txt, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, void* userdata) { ServiceInfo* i = static_cast<ServiceInfo*>(userdata); NetworkServicesProviderAvahi* p = i->provider; ASSERT(r); ASSERT(i); switch (event) { case AVAHI_RESOLVER_FOUND: { NetworkServiceDescription* desc; char address[AVAHI_ADDRESS_STR_MAX]; char* id; char* ztype; char* url; char* config; avahi_address_snprint(address, sizeof(address), a); config = avahi_string_list_to_string(txt); printServiceLine('=', interface, protocol, name, type, domain); LOG(Network, " hostname = [%s]\n" " address = [%s]\n" " port = [%u]\n" " txt = [%s]\n", hostName, address, port, config); id = (char*) avahi_malloc(strlen(name) + strlen(type) + strlen(domain) + 4); sprintf(id, "%s.%s.%s.", name, type, domain); ztype = (char*) avahi_malloc(strlen(type) + strlen("zeroconf:") + 1); sprintf(ztype, "zeroconf:%s", type); url = (char*) avahi_malloc(strlen("http://") + strlen(hostName) + 1); sprintf(url, "http://%s", hostName); if (!(desc = p->getServiceDescriptionById(String::fromUTF8(id)))) p->addServiceDescription(id, name, ztype, url, config); else { desc->setOnline(true); p->notifyNetworkServiceChanged(desc); } avahi_free(id); avahi_free(ztype); avahi_free(url); avahi_free(config); break; } case AVAHI_RESOLVER_FAILURE: LOG_ERROR("Failed to resolve service '%s' of type '%s' in domain '%s': %s\n", name, type, domain, avahi_strerror(avahi_client_errno(p->m_avahiClient))); break; } avahi_service_resolver_free(i->resolver); i->resolver = 0; p->m_resolving--; p->checkTerminate(); }
/* Register a distcc service in DNS-SD/mDNS. If advertise_capabilities is * true, the registration will contain information about the distcc server's * capabilities. If service_type is NULL, the default service type will be * used. advertise_capabilities should be true when using the default * service type. */ void* dcc_zeroconf_register_extended(int advertise_capabilities, const char *service_type, uint16_t port, int n_cpus) { struct context *ctx = NULL; char hostname[_POSIX_HOST_NAME_MAX + 1]; const AvahiPoll *threaded_poll; int len, error; ctx = calloc(1, sizeof(struct context)); if (!ctx) { rs_log_crit("calloc() failed for ctx: %s", strerror(errno)); goto fail; } ctx->advertise_capabilities = advertise_capabilities; ctx->port = port; ctx->n_cpus = n_cpus; /* Prepare service type. Use the supplied value, or the default if * NULL was supplied. */ if (service_type) ctx->service_type = strdup(service_type); else ctx->service_type = strdup(DCC_DNS_SERVICE_TYPE); if (!ctx->service_type) { rs_log_crit("strdup() failed for ctx->service_type: %s", strerror(errno)); goto fail; } /* Prepare service name. This is just the chosen service type with * '@' and the hostname appended. If this collides with anything else, * avahi_alternative_service_name will choose a replacement name. */ if (gethostname(hostname, sizeof(hostname))) { rs_log_crit("gethostname() failed: %s", strerror(errno)); goto fail; } /* Leave room for the '@' and trailing NUL. */ len = strlen(ctx->service_type) + strlen(hostname) + 2; if (!(ctx->name = avahi_malloc(len))) { rs_log_crit("avahi_malloc() failed for ctx->name"); goto fail; } snprintf(ctx->name, len, "%s@%s", ctx->service_type, hostname); /* Create the Avahi client. */ if (!(ctx->threaded_poll = avahi_threaded_poll_new())) { rs_log_crit("Failed to create event loop object."); goto fail; } threaded_poll = avahi_threaded_poll_get(ctx->threaded_poll); if (!(ctx->client = avahi_client_new(threaded_poll, AVAHI_CLIENT_NO_FAIL, client_callback, ctx, &error))) { rs_log_crit("Failed to create client object: %s", avahi_strerror(error)); goto fail; } /* Create the mDNS event handler */ if (avahi_threaded_poll_start(ctx->threaded_poll) < 0) { rs_log_crit("Failed to create thread."); goto fail; } return ctx; fail: if (ctx) dcc_zeroconf_unregister(ctx); return NULL; }