[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