- gint count;
- gchar namebuf[1024];
- guchar *end, *p;
- guint16 type, qclass, rdlength, priority, weight, port;
- guint32 ttl;
- HEADER *header;
- GSrvTarget *target;
- GList *targets;
-
- if (len <= 0)
- {
- GResolverError errnum;
- const gchar *format;
-
- if (len == 0 || herr == HOST_NOT_FOUND || herr == NO_DATA)
- {
- errnum = G_RESOLVER_ERROR_NOT_FOUND;
- format = _("No service record for '%s'");
- }
- else if (herr == TRY_AGAIN)
- {
- errnum = G_RESOLVER_ERROR_TEMPORARY_FAILURE;
- format = _("Temporarily unable to resolve '%s'");
- }
- else
- {
- errnum = G_RESOLVER_ERROR_INTERNAL;
- format = _("Error resolving '%s'");
- }
-
- g_set_error (error, G_RESOLVER_ERROR, errnum, format, rrname);
- return NULL;
- }
-
- targets = NULL;
-
- header = (HEADER *)answer;
- p = answer + sizeof (HEADER);
- end = answer + len;
-
- /* Skip query */
- count = ntohs (header->qdcount);
- while (count-- && p < end)
- {
- p += dn_expand (answer, end, p, namebuf, sizeof (namebuf));
- p += 4;
- }
-
- /* Read answers */
- count = ntohs (header->ancount);
- while (count-- && p < end)
- {
- p += dn_expand (answer, end, p, namebuf, sizeof (namebuf));
- GETSHORT (type, p);
- GETSHORT (qclass, p);
- GETLONG (ttl, p);
- ttl = ttl; /* To avoid -Wunused-but-set-variable */
- GETSHORT (rdlength, p);
-
- if (type != T_SRV || qclass != C_IN)
- {
- p += rdlength;
- continue;
- }
-
- GETSHORT (priority, p);
- GETSHORT (weight, p);
- GETSHORT (port, p);
- p += dn_expand (answer, end, p, namebuf, sizeof (namebuf));
-
- target = g_srv_target_new (namebuf, port, priority, weight);
- targets = g_list_prepend (targets, target);
- }
-
- return g_srv_target_list_sort (targets);