You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
248 lines
6.0 KiB
248 lines
6.0 KiB
5 years ago
|
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||
|
//
|
||
|
// Purpose:
|
||
|
//
|
||
|
// $NoKeywords: $
|
||
|
//
|
||
|
// SMTP RFC 821 Specifies <CR><LF> to terminate lines.
|
||
|
//
|
||
|
// <CR> = Carriage Return C: \r Dec: 13 Hex: 0x0d Oct: 0015
|
||
|
// <LF> = Line Feed ( Newline ) C: \n Dec: 10 Hex: 0x0a Oct: 0012
|
||
|
//
|
||
|
//=============================================================================//
|
||
|
#pragma warning( disable : 4530 )
|
||
|
|
||
|
#include <string>
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <stdarg.h>
|
||
|
#include <time.h>
|
||
|
|
||
|
#include "simplesocket.h"
|
||
|
|
||
|
static int g_ArgCount;
|
||
|
static char **g_Args;
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: simple args API
|
||
|
// Input : argc -
|
||
|
// *argv[] -
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void ArgsInit( int argc, char *argv[] )
|
||
|
{
|
||
|
g_ArgCount = argc;
|
||
|
g_Args = argv;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: tests for the presence of arg "pName"
|
||
|
// Input : *pName -
|
||
|
// Output : Returns true on success, false on failure.
|
||
|
//-----------------------------------------------------------------------------
|
||
|
bool ArgsExist( const char *pName )
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
if ( pName && pName[0] == '-' )
|
||
|
{
|
||
|
for ( i = 0; i < g_ArgCount; i++ )
|
||
|
{
|
||
|
// Is this a switch?
|
||
|
if ( g_Args[i][0] != '-' )
|
||
|
continue;
|
||
|
|
||
|
if ( !stricmp( pName, g_Args[i] ) )
|
||
|
{
|
||
|
return true;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: looks for the arg "pName" and returns it's parameter or pDefault otherwise
|
||
|
// Input : *pName -
|
||
|
// *pDefault -
|
||
|
// Output : const char *
|
||
|
//-----------------------------------------------------------------------------
|
||
|
const char *ArgsGet( const char *pName, const char *pDefault )
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
// don't bother with the last arg, it can't be a switch with a parameter
|
||
|
for ( i = 0; i < g_ArgCount-1; i++ )
|
||
|
{
|
||
|
// Is this a switch?
|
||
|
if ( g_Args[i][0] != '-' )
|
||
|
continue;
|
||
|
|
||
|
if ( !stricmp( pName, g_Args[i] ) )
|
||
|
{
|
||
|
// If the next arg is not a switch, return it
|
||
|
if ( g_Args[i+1][0] != '-' )
|
||
|
return g_Args[i+1];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return pDefault;
|
||
|
}
|
||
|
|
||
|
|
||
|
void Error( const char *pString, ... )
|
||
|
{
|
||
|
va_list list;
|
||
|
va_start( list, pString );
|
||
|
vprintf( pString, list );
|
||
|
printf("Usage: smtpmail -to <address(-es, ';' separated)> -from <address> -subject \"subject text\" [-verbose] [-server server.name] <FILENAME.TXT>\n" );
|
||
|
exit( 1 );
|
||
|
}
|
||
|
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: simple routine to printf() all of the socket traffic for -verbose
|
||
|
// Input : socket -
|
||
|
// *pData -
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void DumpSocket( HSOCKET, const char *pData )
|
||
|
{
|
||
|
printf( "%s", pData );
|
||
|
fflush( stdout );
|
||
|
}
|
||
|
|
||
|
|
||
|
static char *months[] = { "JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC" };
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
// Purpose: mail a text file using the SMTP mail server connected to socket
|
||
|
// Input : socket -
|
||
|
// *pFrom - from address
|
||
|
// *pTo - to address
|
||
|
// *pSubject - subject of the mail
|
||
|
// *fp - text mode file opened
|
||
|
//-----------------------------------------------------------------------------
|
||
|
void MailSendFile( HSOCKET socket, const char *pFrom, const char *pTo[], const char *pSubject, FILE *fp )
|
||
|
{
|
||
|
int i;
|
||
|
char buf[1024];
|
||
|
|
||
|
SocketSendString( socket, "HELO\r\n" );
|
||
|
SocketWait( socket, "\n" );
|
||
|
sprintf( buf, "MAIL FROM: <%s>\r\n", pFrom );
|
||
|
SocketSendString( socket, buf );
|
||
|
SocketWait( socket, "\n" );
|
||
|
for (i = 0; pTo[i] != NULL; i++)
|
||
|
{
|
||
|
sprintf( buf, "RCPT TO: <%s>\r\n", pTo[i] );
|
||
|
SocketSendString( socket, buf );
|
||
|
SocketWait( socket, "\n" );
|
||
|
}
|
||
|
SocketSendString( socket, "DATA\r\n" );
|
||
|
SocketWait( socket, "\n" );
|
||
|
|
||
|
time_t currentTime;
|
||
|
time( ¤tTime );
|
||
|
struct tm *localTime = gmtime( ¤tTime );
|
||
|
|
||
|
sprintf( buf, "DATE: %02d %s %4d %02d:%02d:%02d\r\n", localTime->tm_mday, months[localTime->tm_mon], localTime->tm_year+1900,
|
||
|
localTime->tm_hour, localTime->tm_min, localTime->tm_sec );
|
||
|
|
||
|
SocketSendString( socket, buf );
|
||
|
sprintf( buf, "FROM: %s\r\n", pFrom );
|
||
|
SocketSendString( socket, buf );
|
||
|
for (i = 0; pTo[i] != NULL; i++)
|
||
|
{
|
||
|
sprintf( buf, "TO: %s\r\n", pTo[i] );
|
||
|
SocketSendString( socket, buf );
|
||
|
}
|
||
|
sprintf( buf, "SUBJECT: %s\r\n\r\n", pSubject );
|
||
|
SocketSendString( socket, buf );
|
||
|
|
||
|
while ( !feof( fp ) )
|
||
|
{
|
||
|
fgets( buf, 1024, fp );
|
||
|
|
||
|
// A period on a line by itself would end the transmission
|
||
|
if ( !strcmp( buf, ".\n" ) && !strcmp( buf, ".\r\n" ) )
|
||
|
continue;
|
||
|
|
||
|
SocketSendString( socket, buf );
|
||
|
}
|
||
|
SocketSendString( socket, "\r\n.\r\n" );
|
||
|
SocketWait( socket, "\n" );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
int main( int argc, char *argv[] )
|
||
|
{
|
||
|
|
||
|
ArgsInit( argc, argv );
|
||
|
|
||
|
const char *pServerName = ArgsGet( "-server", "smtp1.valvesoftware.com" );
|
||
|
|
||
|
const char *pTo[100];
|
||
|
pTo[0] = ArgsGet( "-to", NULL );
|
||
|
if ( !pTo[0] )
|
||
|
{
|
||
|
Error( "Must specify a recipient with -to <address(es)>\n" );
|
||
|
}
|
||
|
|
||
|
// split ; separated To string into an array of strings
|
||
|
int c = 0;
|
||
|
char *where;
|
||
|
while (((where = (char *)strchr(pTo[c++],';')) != NULL) && c < 99)
|
||
|
{
|
||
|
*(where++) = '\0';
|
||
|
pTo[c] = where;
|
||
|
}
|
||
|
pTo[c] = NULL;
|
||
|
|
||
|
const char *pFrom = ArgsGet( "-from", NULL );
|
||
|
if ( !pFrom )
|
||
|
{
|
||
|
Error( "Must specify a sender with -from <address>\n" );
|
||
|
}
|
||
|
const char *pSubject = ArgsGet( "-subject", "<NONE>" );
|
||
|
int port = atoi( ArgsGet( "-port", "25" ) );
|
||
|
|
||
|
const char *pFileName = argv[ argc-1 ];
|
||
|
|
||
|
FILE *fp = fopen( pFileName, "r" );
|
||
|
|
||
|
if ( !fp )
|
||
|
{
|
||
|
Error( "Can't open %s\n", pFileName );
|
||
|
}
|
||
|
|
||
|
SocketInit();
|
||
|
|
||
|
// in verbose mode, printf all of the traffic
|
||
|
if ( ArgsExist( "-verbose" ) )
|
||
|
{
|
||
|
SocketReport( DumpSocket );
|
||
|
}
|
||
|
|
||
|
HSOCKET socket = SocketOpen( pServerName, port );
|
||
|
if ( socket )
|
||
|
{
|
||
|
SocketWait( socket, "\n" );
|
||
|
MailSendFile( socket, pFrom, pTo, pSubject, fp );
|
||
|
SocketSendString( socket, "quit\r\n" );
|
||
|
SocketWait( socket, "\n" );
|
||
|
SocketClose( socket );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("Can't open socket to %s:%d\n", pServerName, port );
|
||
|
}
|
||
|
|
||
|
fclose( fp );
|
||
|
|
||
|
SocketExit();
|
||
|
return 0;
|
||
|
}
|