static void cleanup_dbus() { struct server *serv, *tmp, **up; /* unlink and free anything still marked. */ for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp) { tmp = serv->next; if (serv->flags & SERV_MARK) { server_gone(serv); *up = serv->next; if (serv->domain) free(serv->domain); free(serv); } else up = &serv->next; } }
static void dbus_read_servers(DBusMessage *message) { struct server *serv, *tmp, **up; DBusMessageIter iter; union mysockaddr addr, source_addr; char *domain; dbus_message_iter_init(message, &iter); for (serv = daemon->servers; serv; serv = serv->next) if (serv->flags & SERV_FROM_DBUS) serv->flags |= SERV_MARK; while (1) { int skip = 0; if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_UINT32) { u32 a; dbus_message_iter_get_basic(&iter, &a); dbus_message_iter_next (&iter); #ifdef HAVE_SOCKADDR_SA_LEN source_addr.in.sin_len = addr.in.sin_len = sizeof(struct sockaddr_in); #endif addr.in.sin_addr.s_addr = ntohl(a); source_addr.in.sin_family = addr.in.sin_family = AF_INET; addr.in.sin_port = htons(NAMESERVER_PORT); source_addr.in.sin_addr.s_addr = INADDR_ANY; source_addr.in.sin_port = htons(daemon->query_port); } else if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_BYTE) { unsigned char p[sizeof(struct in6_addr)]; unsigned int i; skip = 1; for(i = 0; i < sizeof(struct in6_addr); i++) { dbus_message_iter_get_basic(&iter, &p[i]); dbus_message_iter_next (&iter); if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_BYTE) break; } #ifndef HAVE_IPV6 my_syslog(LOG_WARNING, _("attempt to set an IPv6 server address via DBus - no IPv6 support")); #else if (i == sizeof(struct in6_addr)-1) { memcpy(&addr.in6.sin6_addr, p, sizeof(struct in6_addr)); #ifdef HAVE_SOCKADDR_SA_LEN source_addr.in6.sin6_len = addr.in6.sin6_len = sizeof(struct sockaddr_in6); #endif source_addr.in6.sin6_family = addr.in6.sin6_family = AF_INET6; addr.in6.sin6_port = htons(NAMESERVER_PORT); source_addr.in6.sin6_flowinfo = addr.in6.sin6_flowinfo = 0; source_addr.in6.sin6_scope_id = addr.in6.sin6_scope_id = 0; source_addr.in6.sin6_addr = in6addr_any; source_addr.in6.sin6_port = htons(daemon->query_port); skip = 0; } #endif } else break; do { if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING) { dbus_message_iter_get_basic(&iter, &domain); dbus_message_iter_next (&iter); } else domain = NULL; if (!skip) { for (serv = daemon->servers; serv; serv = serv->next) if ((serv->flags & SERV_FROM_DBUS) && (serv->flags & SERV_MARK)) { if (!(serv->flags & SERV_HAS_DOMAIN) && !domain) { serv->flags &= ~SERV_MARK; break; } if ((serv->flags & SERV_HAS_DOMAIN) && domain && hostname_isequal(domain, serv->domain)) { serv->flags &= ~SERV_MARK; break; } } if (!serv && (serv = whine_malloc(sizeof (struct server)))) { memset(serv, 0, sizeof(struct server)); if (domain) serv->domain = whine_malloc(strlen(domain)+1); if (domain && !serv->domain) { free(serv); serv = NULL; } else { serv->next = daemon->servers; daemon->servers = serv; serv->flags = SERV_FROM_DBUS; if (domain) { strcpy(serv->domain, domain); serv->flags |= SERV_HAS_DOMAIN; } } } if (serv) { if (source_addr.in.sin_family == AF_INET && addr.in.sin_addr.s_addr == 0 && serv->domain) serv->flags |= SERV_NO_ADDR; else { serv->flags &= ~SERV_NO_ADDR; serv->addr = addr; serv->source_addr = source_addr; } } } } while (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_STRING); } for (serv = daemon->servers, up = &daemon->servers; serv; serv = tmp) { tmp = serv->next; if (serv->flags & SERV_MARK) { server_gone(serv); *up = serv->next; free(serv); } else up = &serv->next; } }