summaryrefslogtreecommitdiff
path: root/devtools/smtpmail
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /devtools/smtpmail
downloadarchived-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.cpp162
-rw-r--r--devtools/smtpmail/simplesocket.h40
-rw-r--r--devtools/smtpmail/smtpmail.cpp247
-rw-r--r--devtools/smtpmail/smtpmail.vpc38
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( &currentTime );
+ struct tm *localTime = gmtime( &currentTime );
+
+ 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"
+ }
+}