diff options
| author | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
|---|---|---|
| committer | FluorescentCIAAfricanAmerican <[email protected]> | 2020-04-22 12:56:21 -0400 |
| commit | 3bf9df6b2785fa6d951086978a3e66f49427166a (patch) | |
| tree | 2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /devtools/smtpmail | |
| download | archived-source-engine-2018-hl2-src-master.tar.xz archived-source-engine-2018-hl2-src-master.zip | |
Diffstat (limited to 'devtools/smtpmail')
| -rw-r--r-- | devtools/smtpmail/simplesocket.cpp | 162 | ||||
| -rw-r--r-- | devtools/smtpmail/simplesocket.h | 40 | ||||
| -rw-r--r-- | devtools/smtpmail/smtpmail.cpp | 247 | ||||
| -rw-r--r-- | devtools/smtpmail/smtpmail.vpc | 38 |
4 files changed, 487 insertions, 0 deletions
diff --git a/devtools/smtpmail/simplesocket.cpp b/devtools/smtpmail/simplesocket.cpp new file mode 100644 index 0000000..da2d9a0 --- /dev/null +++ b/devtools/smtpmail/simplesocket.cpp @@ -0,0 +1,162 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: simple TCP socket API for communicating as a TCP client over a TEXT +// connection +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// + +#include <winsock.h> + +#include "simplesocket.h" + + +static REPORTFUNCTION g_SocketReport = NULL; + +//----------------------------------------------------------------------------- +// Purpose: intialize sockets +//----------------------------------------------------------------------------- +void SocketInit( void ) +{ + WSADATA wsData; + + WORD wVersionRequested = MAKEWORD(1, 1); + WSAStartup(wVersionRequested, &wsData); +} + + +//----------------------------------------------------------------------------- +// Purpose: cleanup all socket resources +//----------------------------------------------------------------------------- +void SocketExit( void ) +{ + WSACleanup(); +} + + +//----------------------------------------------------------------------------- +// Purpose: sets up a reporting function +// Input : *pReportFunction - +//----------------------------------------------------------------------------- +void SocketReport( REPORTFUNCTION pReportFunction ) +{ + g_SocketReport = pReportFunction; +} + + +//----------------------------------------------------------------------------- +// Purpose: Open a TCP socket & connect to a given server +// Input : *pServerName - server name (text or ip) +// port - port number of the server +// Output : HSOCKET +//----------------------------------------------------------------------------- +HSOCKET SocketOpen( const char *pServerName, int port ) +{ + SOCKADDR_IN sockAddr; + SOCKET s; + + memset(&sockAddr,0,sizeof(sockAddr)); + + s = socket( AF_INET, SOCK_STREAM, 0 ); + + sockAddr.sin_family = AF_INET; + sockAddr.sin_addr.s_addr = inet_addr(pServerName); + + if (sockAddr.sin_addr.s_addr == INADDR_NONE) + { + LPHOSTENT lphost; + lphost = gethostbyname(pServerName); + if (lphost != NULL) + { + sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr; + } + else + { + WSASetLastError(WSAEINVAL); + return FALSE; + } + } + + sockAddr.sin_port = htons((u_short)port); + + if ( connect( s, (SOCKADDR *)&sockAddr, sizeof(sockAddr) ) == SOCKET_ERROR ) + { +// printf("Socket error:%d\n", WSAGetLastError()) ; + return NULL; + } + + return (HSOCKET)s; +} + + +//----------------------------------------------------------------------------- +// Purpose: close the socket opened with SocketOpen() +// Input : socket - +//----------------------------------------------------------------------------- +void SocketClose( HSOCKET socket ) +{ + SOCKET s = (SOCKET)socket; + closesocket( s ); +} + + +//----------------------------------------------------------------------------- +// Purpose: Write a string to the socket. String is NULL terminated on input, +// but terminator is NOT written to the socket +// Input : socket - +// *pString - string to write +//----------------------------------------------------------------------------- +void SocketSendString( HSOCKET socket, const char *pString ) +{ + if ( !pString ) + return; + + int len = (int)strlen( pString ); + + if ( !len ) + return; + + if ( send( (SOCKET)socket, pString, len, 0 ) != SOCKET_ERROR ) + { + if ( g_SocketReport ) + { + g_SocketReport( socket, pString ); + } + } + else + { +// printf("Send failed\n"); + } +} + + +//----------------------------------------------------------------------------- +// Purpose: receive input from a socket until a certain string is received +// ASSUME: socket data is all text +// Input : socket - +// *pString - string to match, if NULL, just poll the socket once +//----------------------------------------------------------------------------- +void SocketWait( HSOCKET socket, const char *pString ) +{ + char buf[1024]; + + bool done = false; + while ( !done ) + { + int len = recv( (SOCKET)socket, buf, sizeof(buf)-1, 0 ); + buf[len] = 0; + if ( g_SocketReport ) + { + g_SocketReport( socket, buf ); + } + if ( !pString || strstr( buf, pString ) ) + return; + } +} + diff --git a/devtools/smtpmail/simplesocket.h b/devtools/smtpmail/simplesocket.h new file mode 100644 index 0000000..4b9fdb1 --- /dev/null +++ b/devtools/smtpmail/simplesocket.h @@ -0,0 +1,40 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: simple TCP socket API for communicating as a TCP client over a TEXT +// connection +// +// $Workfile: $ +// $Date: $ +// +//----------------------------------------------------------------------------- +// $Log: $ +// +// $NoKeywords: $ +//=============================================================================// + +#ifndef SIMPLESOCKET_H +#define SIMPLESOCKET_H +#pragma once + +// opaque socket type +typedef struct socket_s socket_t, *HSOCKET; + +// Socket reporting function +typedef void ( *REPORTFUNCTION )( HSOCKET socket, const char *pString ); + +extern HSOCKET SocketOpen( const char *pServerName, int port ); +extern void SocketClose( HSOCKET socket ); +extern void SocketSendString( HSOCKET socket, const char *pString ); + +// This should probably return the data so we can handle errors and receive data +extern void SocketWait( HSOCKET socket, const char *pString ); + +// sets the reporting function +extern void SocketReport( REPORTFUNCTION pReportFunction ); +extern void SocketInit( void ); +extern void SocketExit( void ); + + + + +#endif // SIMPLESOCKET_H diff --git a/devtools/smtpmail/smtpmail.cpp b/devtools/smtpmail/smtpmail.cpp new file mode 100644 index 0000000..ea0d9f9 --- /dev/null +++ b/devtools/smtpmail/smtpmail.cpp @@ -0,0 +1,247 @@ +//========= 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; +} diff --git a/devtools/smtpmail/smtpmail.vpc b/devtools/smtpmail/smtpmail.vpc new file mode 100644 index 0000000..d232d66 --- /dev/null +++ b/devtools/smtpmail/smtpmail.vpc @@ -0,0 +1,38 @@ +//----------------------------------------------------------------------------- +// SMTPMAIL.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR "..\.." +$Macro OUTBINDIR "..\bin" + +$Include "$SRCDIR\vpc_scripts\source_exe_con_base.vpc" + +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE,..\common,..\vmpi" + $PreprocessorDefinitions "$BASE;MACRO_MATHLIB;PROTECTED_THINGS_DISABLE" + } + + $Linker + { + $AdditionalDependencies "$BASE ws2_32.lib odbc32.lib odbccp32.lib" + } +} + +$Project "Smtpmail" +{ + $Folder "Source Files" + { + $File "smtpmail.cpp" + $File "simplesocket.cpp" + } + + $Folder "Header Files" + { + $File "simplesocket.h" + } +} |