Advertisement
C_Volume2 Complete Applications #82044

Sendmail for Windows 98/NT

A simple sendmail utility for Windows 98/NT at the TCPIP socket level, based on RFC821. A needed addon for Windows. Operated in command-line/console mode.

AI

AI Summary: This codebase represents a historical implementation of the logic described in the metadata. Our preservation engine analyzes the structure to provide context for modern developers.

Source Code
original-source
/*
 * FILENAME:  sendmail.cpp
 *
 * DESCRIPTION:  A simple text-based implementation for the popular sendmail tool.
 *     Useful for Windows, since sendmail is not included
 *
 * BUILD DEPENDENCIES: Visual C++ 6.0 - must include ws2_32.lib during linking
 *      Visualage C++ 3.5.9 - must include wsock32.lib during linking
 *
 * Change History:
 * Date    Description
 * -------------------------------------------------------------------------------------
 * 03/04/2002  File created
 *
 *
 * TODO:
 * - mail server name resolution
 * - attachment implementation
 * - reading message text from a file
 * - reading subject line from a file with truncation
 * - integration with PHP/mail function
 *
 */
#ifdef WIN32
#include <windows.h>
#include <winsock.h>
#define WINSOCK_VERSION 512  
#endif // WIN32
#include <stdio.h>
#include <string.h>
#define CR '\r' // carriage return
#define LF '\n' // line feed
#define SMTP_PORT  25  // IP Port for the SMTP Server
#define MAXBUF   80  // Maximum buffer size
void main(int argc,char **argv)
{
 char *remote_host;  // must use ip address
 char *sender;
 char *receiver;
 char *subject;
 char *message;
 //
 // Checks the command line arguments
 //
 if (argc == 6) {
  remote_host = argv[1];
  sender = argv[2];
  receiver = argv[3];
  subject = argv[4];
  message = argv[5];
 } else {
  printf("usage: <host ip> <sender> <receiver> <subject> <message>\n");
  return;
 }
#ifdef WIN32
 // 
 // Initializes the Winsock stack, required for Windows
 //
 WORD wVersionRequested;
 WSADATA wsaData;
 int err;
 
 wVersionRequested = MAKEWORD( 2, 2 );
 
 err = WSAStartup( wVersionRequested, &wsaData );
 if ( err != 0 ) {
  /* Tell the user that we could not find a usable */
  /* WinSock DLL.         */
  return;
 }
#endif // WIN32 
 
 PROTOENT *proto;
 SOCKET s;
 SOCKADDR_IN addr;
 SOCKADDR_IN addrServer;
 char buf[MAXBUF];
 char req[MAXBUF];
 //
 // Creates and opens a socket with the SMTP Mail Server
 //
 proto = getprotobyname("tcp");
 s = socket(PF_INET,SOCK_STREAM,proto->p_proto);
 if (s != INVALID_SOCKET) {
  addr.sin_family = PF_INET;
  addr.sin_port = 0;
  addr.sin_addr.s_addr = htonl(INADDR_ANY);
  if (bind (s, (LPSOCKADDR)&addr,sizeof(addr)) == SOCKET_ERROR) {
   printf("bind() generated error %d\n",WSAGetLastError());
  } else {
   addrServer.sin_family = PF_INET;
   addrServer.sin_port = htons(SMTP_PORT);
   addrServer.sin_addr.s_addr = inet_addr(remote_host);
   if (connect(s,(LPSOCKADDR)&addrServer,sizeof(addrServer)) == SOCKET_ERROR) {
    printf("connect() generated error %d\n",WSAGetLastError());
   } else {
 
    //
    // Tells the SMTP Server that a mail operation is about to begin
    //
    sprintf(req,"HELO %s\r\n",remote_host);
    if (send(s,req,strlen(req),0) == SOCKET_ERROR) {
     printf("send() generated error %d at line %d\n",WSAGetLastError(),__LINE__);
    } else {
     strncpy(buf,"\0",80);
     if (recv(s,buf,sizeof(buf),0) == SOCKET_ERROR) {
      printf("recv() generated error %d at line %d\n",WSAGetLastError(),__LINE__);
     } else {
#ifdef DEBUG
      printf("recv() [%s] at %d\n",buf,__LINE__);
#endif // DEBUG
     }
    }
    //
    // Tells the SMTP Server who is sending this message
    //
    sprintf(req,"MAIL FROM:<%s>\r\n",sender);
    if (send(s,req,strlen(req),0) == SOCKET_ERROR) {
     printf("send() generated error %d at line %d\n",WSAGetLastError(),__LINE__);
    } else {
     strncpy(buf,"\0",80);
     if (recv(s,buf,sizeof(buf),0) == SOCKET_ERROR) {
      printf("recv() generated error %d at line %d\n",WSAGetLastError(),__LINE__);
     } else {
#ifdef DEBUG
      printf("recv() [%s] at %d\n",buf,__LINE__);
#endif // DEBUG
     }
    }
    //
    // Tells the SMTP Server who will receive this message
    //
    sprintf(req,"RCPT TO: <%s>\r\n",receiver);
    if (send(s,req,strlen(req),0) == SOCKET_ERROR) {
     printf("send() generated error %d at line %d\n",WSAGetLastError(),__LINE__);
    } else {
     strncpy(buf,"\0",80);
     if (recv(s,buf,sizeof(buf),0) == SOCKET_ERROR) {
      printf("recv() generated error %d at line %d\n",WSAGetLastError(),__LINE__);
     } else {
#ifdef DEBUG
      printf("recv() [%s] at %d\n",buf,__LINE__);
#endif // DEBUG
     }
    }
    //
    // Defines the start of the message by adding the subject heading followed by
    // a CR. The subject is required if your want to see a subject in your
    // mail client.
    //
    sprintf(req,"DATA\r\nSubject: %s\r",subject);
    if (send(s,req,strlen(req),0) == SOCKET_ERROR) {
     printf("send() generated error %d at line %d\n",WSAGetLastError(),__LINE__);
    } else {
     if (recv(s,buf,sizeof(buf),0) == SOCKET_ERROR) {
      printf("recv() generated error %d at line %d\n",WSAGetLastError(),__LINE__);
     } else {
#ifdef DEBUG
      printf("recv() [%s] at %d\n",buf,__LINE__);
#endif // DEBUG
     }
    }
    //
    // Adds the receiver to the message header, required if you want
    // to the see the receiver's name in your mail reader 
    //
    sprintf(req,"To: <%s>",receiver);
    if (send(s,req,strlen(req),0) == SOCKET_ERROR) {
     printf("send() generated error %d at line %d\n",WSAGetLastError(),__LINE__);
    }
    //
    // Sends the actual text meesage to the SMTP Server
    //
    sprintf(req,"\r\n%s\r\n.\r\n",message);
    if (send(s,req,strlen(req),0) == SOCKET_ERROR) {
     printf("send() generated error %d at line %d\n",WSAGetLastError(),__LINE__);
    }
    //
    // Closes the SMTP communication and tells the SMTP-Server to process mail
    //
    sprintf(req,"QUIT\r\n");
    if (send(s,req,strlen(req),0) == SOCKET_ERROR) {
     printf("send() generated error %d at line %d\n",WSAGetLastError(),__LINE__);
    } else {
     strncpy(buf,"\0",80);
     if (recv(s,buf,sizeof(buf),0) == SOCKET_ERROR) {
      printf("recv() generated error %d at line %d\n",WSAGetLastError(),__LINE__);
     } else {
#ifdef DEBUG
      printf("recv() [%s] at %d\n",buf,__LINE__);
#endif // DEBUG
     }
    }
   }
  }
  closesocket(s);
 }
 if ( LOBYTE( wsaData.wVersion ) != WINSOCK_VERSION ||
   HIBYTE( wsaData.wVersion ) != WINSOCK_VERSION ) {
  WSACleanup( );
  return; 
 }
}
Original Comments (3)
Recovered from Wayback Machine