dmc

dynamic mail client
git clone git://git.suckless.org/dmc
Log | Files | Refs | README | LICENSE

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 }