/ ngsmtp1.c: NET/guard+ SMTP client. Use gcc within Cygwin or other environment
// Vers. 1.05 - 05.Mar.2006
// k.d.walter@t-online.de
// Includes
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
// Defines
#define VERSION "1.05 - 05.Mar.2006"
// Functions: 1. main - The one and only ...
int main (int argc, char* argv[])
{
int nLen= sizeof (struct sockaddr), nRet, s1;
long lRet;
char szBuf[1024];
struct sockaddr_in saServer;
struct tm *tmPtr;
time_t currTime;
// Check for IP address and port argument. Print usage if errors...
if (argc != 4) {
printf ("\n Usage.: ngsmtp <\"E-Mail Message\">");
printf ("\n Sample: ngsmtp 192.168.0.1 info@ist1.de \"test message...\"\n");
exit (0);
}
// Check for valid IP address
lRet= inet_addr (argv[1]);
if (lRet == INADDR_NONE) {
printf ("\n No valid IP address.\n");
exit (0);
}
// Create a TCP/IP stream socket...
s1= socket (AF_INET, SOCK_STREAM, 0);
// ... and check for error...
if (s1 < 0) {
printf ("\n Can not create socket.\n");
exit (0);
}
// Fill in the internet address structure...
saServer.sin_family= AF_INET; // Address family
saServer.sin_addr.s_addr= inet_addr (argv[1]); // IP address
saServer.sin_port= htons (25); // Portnumber
memset (&(saServer.sin_zero), 0x00, 8); // Zero the rest...
// Connect to server...
printf ("\n... Try to connect to %s:25.", argv[1]);
fflush (stdout);
nRet= connect (s1, (struct sockaddr *) &saServer, nLen);
// Check for errors...
if (nRet != 0) {
printf ("\n Can not connect to SMTP server.\n");
close (s1);
exit (0);
}
// Wait for first server message (220 ...) ...
memset (szBuf, 0, sizeof (szBuf));
nRet= recv (s1, szBuf, sizeof (szBuf), 0);
printf ("\nRX: %s", szBuf);
// Get current time...
(void) time (&currTime);
tmPtr= localtime (&currTime);
// Send "HELO ..." and wait for server answer (250 ...) ...
sprintf (szBuf, "HELO user\r\n");
printf ("\nTX: %s", szBuf);
send (s1, szBuf, strlen (szBuf), 0);
memset (szBuf, 0, sizeof (szBuf));
nRet= recv (s1, szBuf, sizeof (szBuf), 0);
printf ("RX: %s", szBuf);
if (strncmp (szBuf, "250", 3)) { // Check for server answer "250"
printf ("\nE1: SMTP server error.\n");
close (s1);
exit (0);
}
// Send "MAIL FROM: ..." and wait for server answer (250 ...) ...
sprintf (szBuf, "MAIL FROM: \r\n");
printf ("\nTX: %s", szBuf);
send (s1, szBuf, strlen (szBuf), 0);
memset (szBuf, 0, sizeof (szBuf));
nRet= recv (s1, szBuf, sizeof (szBuf), 0);
printf ("RX: %s", szBuf);
if (strncmp (szBuf, "250", 3)) { // Check for server answer "250"
printf ("\nE2: SMTP server error.\n");
close (s1);
exit (0);
}
// Send "RCPT TO: ..." and wait for server answer (250 ...) ...
sprintf (szBuf, "RCPT TO: <%s>\r\n", argv[2]);
printf ("\nTX: %s", szBuf);
send (s1, szBuf, strlen (szBuf), 0);
memset (szBuf, 0, sizeof (szBuf));
nRet= recv (s1, szBuf, sizeof (szBuf), 0);
printf ("RX: %s", szBuf);
if (strncmp (szBuf, "250", 3)) { // Check for server answer "250"
printf ("\nE3: SMTP server error.\n");
close (s1);
exit (0);
}
// Send "DATA" and wait for server answer (354 ...) ...
sprintf (szBuf, "DATA\r\n");
printf ("\nTX: %s", szBuf);
send (s1, szBuf, strlen (szBuf), 0);
memset (szBuf, 0, sizeof (szBuf));
nRet= recv (s1, szBuf, sizeof (szBuf), 0);
printf ("RX: %s", szBuf);
if (strncmp (szBuf, "354", 3)) { // Check for server answer "354"
printf ("\nE4: SMTP server error.\n");
close (s1);
exit (0);
}
// Send 1. line of header...
sprintf (szBuf, "From: \r\n");
printf ("\nTX: %s", szBuf);
send (s1, szBuf, strlen (szBuf), 0);
// Send 2. line of header...
sprintf (szBuf, "To: <%s>\r\n", argv[2]);
printf ("TX: %s", szBuf);
send (s1, szBuf, strlen (szBuf), 0);
// Send 3. line of header...
sprintf (szBuf, "Subject: NET/guard+ - Current System State at %02d:%02d:%02d\r\n",
tmPtr->tm_hour, tmPtr->tm_min, tmPtr->tm_sec);
printf ("TX: %s", szBuf);
send (s1, szBuf, strlen (szBuf), 0);
// Send 4. line of header with one blank line...
sprintf (szBuf, "Content-type: text/plain\r\n\r\n");
printf ("TX: %s", szBuf);
send (s1, szBuf, strlen (szBuf), 0);
// Send one line of data with NET/guard+ version number and build date...
sprintf (szBuf, "NET/guard+ SMTP Client Vers. "VERSION"\r\n");
printf ("TX: %s", szBuf);
send (s1, szBuf, strlen (szBuf), 0);
// Send one line of data as separator...
sprintf (szBuf, "-----------------------------------------------\r\n");
printf ("TX: %s", szBuf);
send (s1, szBuf, strlen (szBuf), 0);
// Send one line of data with command line argument...
sprintf (szBuf, "%s\r\n", argv[3]);
printf ("TX: %s", szBuf);
send (s1, szBuf, strlen (szBuf), 0);
// Send end of data and wait for server answer (250 ...) ...
sprintf (szBuf, ".\r\n");
printf ("TX: %s", szBuf);
send (s1, szBuf, strlen (szBuf), 0);
memset (szBuf, 0, sizeof (szBuf));
nRet= recv (s1, szBuf, sizeof (szBuf), 0);
printf ("RX: %s", szBuf);
if (strncmp (szBuf, "250", 3)) { // Check for server answer "250"
printf ("\nE5: SMTP server error.\n");
close (s1);
exit (0);
}
// Send "QUIT" and wait for server answer (221 ...) ...
sprintf (szBuf, "QUIT\r\n");
printf ("\nTX: %s", szBuf);
send (s1, szBuf, strlen (szBuf), 0);
memset (szBuf, 0, sizeof (szBuf));
nRet= recv (s1, szBuf, sizeof (szBuf), 0);
printf ("RX: %s", szBuf);
if (strncmp (szBuf, "221", 3)) { // Check for server answer "221"
printf ("\nE6: SMTP server error.\n");
close (s1);
exit (0);
}
// OK: Exit this SMTP client code ...
close (s1);
exit (1);
}
|