[Raw Msg Headers][Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: alternatives to ETRN



Once Imre Fitos wrote:
>	The discussion quickly went away from ETRN, so more than likely I
>have to hack something together that accepts a message with a domain in it
>and telnets to port 25, says EHLO and the ETRN domain.

	You are likely looking for this:


/*
 * $Id: turnme.c,v 1.3 1997/07/23 12:06:25 alexis Exp $
 *
 * Alexis Yushin, NLnet Development BV, 1997
 *
 */

#include <sys/types.h>
#include <sys/socket.h>

#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <strings.h>
#include <syslog.h>
#include <unistd.h>

#include <netinet/in.h>

#define	SMTP_PORT		25
#define	SMTP_BUFFER		128
#define HOSTNAME_BUFFER		64

static struct sockaddr_in	remote;
static int			s;
static FILE			*ws, *rs;
static char			buffer[SMTP_BUFFER];
static char			hostname[HOSTNAME_BUFFER];
static int			verbose;

extern	void	usage();
extern	void	goodbye();
extern	char	*smtp_read();
extern	struct hostent	*gethostbyname2();

/*
 * Connects to the specified host and issue HELO + ETRN command for the
 * domain.
 *
 */
int
main(argc, argv)
    int argc;
    char **argv;
{
    register int c, s;
    struct hostent *host;
    char *progname;

    extern char *optarg;
    extern int optind;

    int delay = 0;

    if((progname = rindex(argv[0], '/')) == NULL) {
	progname = argv[0];
    } else {
	progname++;
    }

    verbose = 0;
    remote.sin_family = AF_INET;
    remote.sin_addr.s_addr = -1;
    remote.sin_port = htons(SMTP_PORT);

    openlog("turnme", LOG_PID, LOG_MAIL);

    while((c = getopt(argc, argv, "h:p:l:vd:")) != -1) {
	switch(c) {
	    case 'h':
		if((host = gethostbyname2(optarg, AF_INET)) == NULL) {
		    syslog(LOG_ERR, "cannot resolve name %s: %s",
			 optarg, hstrerror(h_errno));
		    exit(1);
		}
		/* We always use the first address */
		remote.sin_addr.s_addr = *(u_long *)host->h_addr_list[0];
		break;
	    case 'p':
		if((remote.sin_port = htons(atoi(optarg))) == 0) {
		    syslog(LOG_ERR, "incorrect port number %s", optarg);
		    exit(1);
		}
		break;
	    case 'l':
		/* Not used, ignore siletly */
		break;
	    case 'v':
#ifdef LOG_PERROR		/* Nothing to do if not... */
		closelog();
		openlog("turnme", LOG_PID | LOG_PERROR, LOG_MAIL);
#endif
		verbose++;
		break;
	    case 'd':
		delay = atoi(optarg);
		break;
	    default:
		usage();
	}
    }
    argc -= optind;
    argv += optind;
    if(remote.sin_addr.s_addr == -1 || argc == 0) {
	usage();
    }
    if(gethostname(hostname, HOSTNAME_BUFFER) == -1) {
	syslog(LOG_ERR, "cannot find out my hostname: %m");
	exit(1);
    }
    if(delay)
	sleep(delay);
    /* Initialization is done by this moment */
    if((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
	syslog(LOG_ERR, "cannot create socket %m");
	exit(1);
    }
    if(verbose) {
	fprintf(stdout, "Establishing connection...\n");
    }
    if(connect(s, (struct sockaddr *)&remote, sizeof(struct sockaddr_in))) {
	syslog(LOG_ERR, "connect(2) failed: %m");
	exit(1);
    }
    if((rs = fdopen(s, "r")) == NULL || (ws = fdopen(s, "w")) == NULL) {
	syslog(LOG_ERR, "cannot associate a file handler with the socket");
	exit(1);
    }
    if(smtp_read(220) == NULL) {	/* The msssage is not greeting */
	syslog(LOG_ERR, "no greeting from remote");
	goodbye(1);
    }
    fprintf(ws, "EHLO %s\n", hostname);
    if(verbose) {
	fprintf(stdout, ">>> EHLO %s\n", hostname);
    }
    fflush(ws);
    if(smtp_read(250) == NULL) {	/* Wont talk with us */
	syslog(LOG_ERR, "the remote will not talk to us");
	goodbye(1);
    }
    while(argc) {
	fprintf(ws, "ETRN %s\n", *argv);
	if(verbose) {
	    fprintf(stdout, ">>> ETRN %s\n", *argv);
	}
	fflush(ws);
	if(smtp_read(250) == NULL) {	/* TURNME failed */
	    syslog(LOG_ERR, "ETRN command failed for %s", *argv);
	    goodbye(1);
	}
	argc--;
	argv++;
    }
    goodbye(0);
    /* Never reached */
}

/*
 * Prints usage and exits the program.
 */
void
usage()
{
     fprintf(stderr, "usage: turnme [-v] -h hostname [-p port] [-l lock]"
	" [-d delay] domains\n");
     exit(1);
}

/*
 * Say QUIT and leave
 */
void
goodbye(exitcode)
    int exitcode;
{
    fprintf(ws, "QUIT\n");
    if(verbose) {
	fprintf(stdout, ">>> QUIT\n");
    }
    fflush(ws);
    fclose(rs);
    fclose(ws);
    close(s);
    closelog();
    exit(exitcode);
}

/*
 * Read and return the last SMTP response if matches int
 *
 */
char *
smtp_read(code)
    int code;
{
    int size;
    int response;

    while(fgets(buffer, SMTP_BUFFER, rs) != NULL) {
	if(verbose) {
	     fputs(buffer, stdout);
	}
	if(buffer[3] != ' ') {
	    continue;
	}
	buffer[3] = '\0';
	if(atoi(buffer) != code) {
	    return NULL;
	}
	buffer[3] = ' ';
	return buffer;
    }
    syslog(LOG_ERR, "cannot read from stream: %m");
    /* Not reached */
}

>	Any errors in this?

	Hopefully not :)
							alexis
-- 
	How can a flower so beautiful, be so laiden down with dew