/*
** Copyright (c) 2018 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)
**
** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
** Author contact information:
** drh@hwaci.com
** http://www.hwaci.com/drh/
**
*******************************************************************************
**
** Implementation of SMTP (Simple Mail Transport Protocol) according
** to RFC 5321.
*/
#include "config.h"
#include "smtp.h"
#include <assert.h>
#if !defined(FOSSIL_OMIT_SMTP)
#if defined(_WIN32)
/* Don't yet know how to do this on windows */
#else
# include <sys/types.h>
# include <netinet/in.h>
# include <arpa/nameser.h>
# include <resolv.h>
#endif
#endif /* !defined(FOSSIL_OMIT_SMTP) */
/*
** Find the hostname for receiving email for the domain given
** in zDomain. Return NULL if not found or not implemented.
** If multiple email receivers are advertized, pick the one with
** the lowest preference number.
**
** The returned string is obtained from fossil_malloc()
** and should be released using fossil_free().
*/
char *smtp_mx_host(const char *zDomain){
#if !defined(_WIN32) && !defined(FOSSIL_OMIT_SMTP)
int nDns; /* Length of the DNS reply */
int rc; /* Return code from various APIs */
int i; /* Loop counter */
int iBestPriority = 9999999; /* Best priority */
int nRec; /* Number of answers */
ns_msg h; /* DNS reply parser */
const unsigned char *pBest = 0; /* RDATA for the best answer */
unsigned char aDns[5000]; /* Raw DNS reply content */
char zHostname[5000]; /* Hostname for the MX */
nDns = res_query(zDomain, C_IN, T_MX, aDns, sizeof(aDns));
if( nDns<=0 ) return 0;
res_init();
rc = ns_initparse(aDns,nDns,&h);
if( rc ) return 0;
nRec = ns_msg_count(h, ns_s_an);
for(i=0; i<nRec; i++){
ns_rr x;
int priority, sz;
const unsigned char *p;
rc = ns_parserr(&h, ns_s_an, i, &x);
if( rc ) continue;
p = ns_rr_rdata(x);
sz = ns_rr_rdlen(x);
if( sz>2 ){
priority = p[0]*256 + p[1];
if( priority<iBestPriority ){
pBest = p;
iBestPriority = priority;
}
}
}
if( pBest ){
ns_name_uncompress(aDns, aDns+nDns, pBest+2,
zHostname, sizeof(zHostname));
return fossil_strdup(zHostname);
}
#endif /* not windows */
return 0;
}
/*
** COMMAND: test-find-mx
**
** Usage: %fossil test-find-mx DOMAIN ...
**
** Do a DNS MX lookup to find the hostname for sending email for
** DOMAIN.
*/
void test_find_mx(void){
int i;
if( g.argc<2 ){
usage("DOMAIN ...");
}
for(i=2; i<g.argc; i++){
char *z = smtp_mx_host(g.argv[i]);
fossil_print("%s: %s\n", g.argv[i], z);
fossil_free(z);
}
}
|