+ /* Make another DNS query for textual data; this shouldn't
+ * be a performance hit, since it'll now be cached at the
+ * nameserver we're using.
+ */
+ len = res_query(domain, C_IN, T_TXT, answer, PACKETSZ);
+ if (server_shutting_down) {
+ if (txtbuf != NULL) {
+ snprintf(txtbuf, txtbufsize, "System shutting down");
+ }
+ if (need_to_free_answer) free(answer);
+ free(result);
+ return (1);
+ }
+
+ /* Just in case there's no TXT record... */
+ if (len ==(-1)) {
+ if (txtbuf != NULL) {
+ snprintf(txtbuf, txtbufsize, "Message rejected due to known spammer source IP address");
+ }
+ if (need_to_free_answer) free(answer);
+ free(result);
+ return(1);
+ }
+
+ /* Skip the header and the address we queried. */
+ cp = answer + sizeof( HEADER );
+ while( *cp != '\0' ) {
+ a = *cp++;
+ while( a-- )
+ cp++;
+ }
+
+ /* This seems to be a bit of magic data that we need to
+ * skip. I wish there were good online documentation
+ * for programming for libresolv, so I'd know what I'm
+ * skipping here. Anyone reading this, feel free to
+ * enlighten me.
+ */
+ cp += 1 + NS_INT16SZ + NS_INT32SZ;
+
+ /* Skip the type, class and ttl. */
+ cp += (NS_INT16SZ * 2) + NS_INT32SZ;
+
+ /* Get the length and end of the buffer. */
+ NS_GET16(c, cp);
+ cend = cp + c;
+
+ /* Iterate over any multiple answers we might have. In
+ * this context, it's unlikely, but anyway.
+ */
+ rp = (u_char *) result;
+ rend = (u_char *) result + RESULT_SIZE - 1;
+ while (cp < cend && rp < rend) {
+ a = *cp++;
+ if (a != 0) {
+ for (b = a; b > 0 && cp < cend && rp < rend; b--) {
+ if (*cp == '\n' || *cp == '"' || *cp == '\\') {
+ *rp++ = '\\';
+ }
+ *rp++ = *cp++;
+ }
+ }
+ }
+ *rp = '\0';
+ if (txtbuf != NULL) {
+ long len;
+ len = snprintf(txtbuf, txtbufsize, "%s", result);
+
+ /* Remove nonprintable characters */
+ for (p = txtbuf; *p != '\0'; p++) {
+ if (!isprint(*p)) {
+ memmove (p,
+ p + 1,
+ len - (p - txtbuf) - 1);
+ }
+ }
+ }
+ if (need_to_free_answer) free(answer);
+ free(result);
+ return(1);