smtp.c (1988B)
1 /* dmc - dynamic mail client 2 * See LICENSE file for copyright and license details. 3 */ 4 5 #include <stdio.h> 6 #include <stdio.h> 7 #include <string.h> 8 #include <stdlib.h> 9 #include <netinet/in.h> 10 #include <sys/types.h> 11 #include <arpa/nameser.h> 12 #include <resolv.h> 13 #define BIND_4_COMPAT 14 15 static int resmx(const char *domain) { 16 char host[NS_MAXDNAME+1]; 17 char last[NS_MAXDNAME+1]; 18 typedef union { 19 HEADER head; 20 char buf[PACKETSZ]; 21 } pkt_t; 22 unsigned char buf[PACKETSZ]; 23 unsigned char *rrptr; 24 pkt_t *pkt = (pkt_t *)buf; 25 int querylen, len, n, exprc; 26 int rrtype, antrrtype; 27 int rrpayloadsz; 28 29 querylen = res_querydomain (domain, "", C_IN,T_MX, (void*)&buf, PACKETSZ); 30 31 if (ntohs (pkt->head.rcode) == NOERROR) { 32 n = ntohs (pkt->head.ancount); 33 if (n==0) { 34 fprintf(stderr, "No MX found\n"); 35 return 1; 36 } 37 38 /* expand DNS query */ 39 len = dn_expand (buf, 40 buf + querylen, buf + sizeof(HEADER), 41 host, sizeof (host)); 42 if (len<0) { 43 fprintf (stderr, "No MX found\n"); 44 return 1; 45 } 46 47 rrptr = buf + len + 4 + sizeof (HEADER); 48 49 while (rrptr < buf+querylen) { 50 /* expand NAME resolved */ 51 exprc = dn_expand (buf, buf+querylen, rrptr, host, sizeof (host)); 52 if (exprc<0) { 53 fprintf (stderr, "No MX found\n"); 54 return 1; 55 } 56 rrptr += exprc; 57 rrtype = (rrptr[0]<<8|rrptr[1]); 58 rrpayloadsz = (rrptr[8]<<8|rrptr[9]); 59 rrptr += 10; 60 switch (rrtype) { 61 /* TODO support for IPv6: case T_AAAA: */ 62 case T_A: 63 if (strcmp (host, last)) { 64 printf ("%s\n", host); 65 if (--n==0) querylen=0; 66 } 67 break; 68 } 69 antrrtype = rrtype; 70 rrptr += rrpayloadsz; 71 } 72 } else { 73 printf ("%s\n", domain); 74 return 1; 75 } 76 return 0; 77 } 78 79 int main(int argc, char **argv) { 80 if (argc>1) { 81 char *ch = strchr(argv[1], '@'); 82 if (!ch) { 83 /* do the daemon stuff here */ 84 fprintf (stderr, "TODO: SMTP protocol not yet implemented\n"); 85 } else return resmx (ch+1); 86 } else printf ("Usage: dmc-smtp [user@domain] # Get MX for domain\n"); 87 return 0; 88 }