php mail() --> sendmail = crash

Hi,

So I'm having a bit of a problem with sendmail and php. I use Simple Machine Forums, and would like to get my email working again.

My problem is that when I finally did point php.ini to the correct sendmail location, all the email addresses that were real would go through to their inbox, but all the bogus spam emails would hang sendmail and cause it to spawn near 100 processes of itself. The last time that happened, my entire server froze up until I did a 30 minute process of logging into ssh and killall sendmail.

So, what I'm asking is if there is an easy-to-configure outgoing MTA, or if there's a way for sendmail to try the email once and drop it.
 
Alex4108 said:
So, what I'm asking is if there is an easy-to-configure outgoing MTA...

You might want to look into mail/ssmtp, OR you can use my simplistic do-it-yourself-in-C solution:

Code:
//  SMTPSend.c
//
//  Created by Dr. Rolf Jansen on 2011-05-04.
//  Copyright 2011 InstantWare - Dr. Rolf Jansen. All rights reserved.
//  
//  Permission to use, copy, modify, and distribute this software for any
//  purpose with or without fee is hereby granted, provided that the above
//  copyright notice and this permission notice appear in all copies.
//
//  THIS SOFTWARE IS PROVIDED BY InstantWare - Dr. Rolf Jansen "AS IS"
//  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL InstantWare - Dr. Rolf Jansen
//  BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
//  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
//  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
//  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
//  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
//  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
//  THE POSSIBILITY OF SUCH DAMAGE.
//
// cc SMTPSend.c -std=c99 -Os -g0 -o /usr/local/bin/SMTPSend


// Standard C includes
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>

// header files which must be included for
// high level DNS services and socket connections
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

// constants
#define defaultBufferSize  4096


short doSMTPTransaction(int smtpSocket, char *sendBuffer, long sendBufferSize, char *receiveBuffer)
{
   long receiveSize = 0;

   if (sendBuffer && send(smtpSocket, sendBuffer, sendBufferSize, 0) == -1)
      return 1000;

   else if (receiveBuffer && (receiveSize = recv(smtpSocket, receiveBuffer, defaultBufferSize - 1, 0)) < 0)
      return 2000;

   if (receiveSize != 0)
   {
      receiveBuffer[receiveSize] = '\0';
      return strtol(receiveBuffer, NULL, 10);
   }

   else
      return 0;
}


// argv[1]:    fully qualified sender address
// argv[2..n]: fully qualified recipient addresses
int main(int argc, const char *argv[])
{
   int    i, smtpCode = 0, resultCode = 1;
   long   smtpSocket, sendBufferSize;
   char   c = 0;
   char   transferBuffer[defaultBufferSize];

   struct sockaddr_in  address;
   struct hostent     *host = NULL;

   char  *smtpRelayHostName = "smtp.relay.dom";       // replace with the IP or address of the relay server
   char  *smtpAuthLoginID   = "dXNlcm5hbWUK\r\n";     // replace with your base 64 encoded SMTP login ID
   char  *smtpAuthPassword  = "cGFzc3dvcmQK\r\n";     // replace with your base 64 encoded SMTP auth password

   if (!inet_aton(smtpRelayHostName, &address.sin_addr))
      if (host = gethostbyname(smtpRelayHostName))
         address.sin_addr = *(struct in_addr*)host->h_addr;
      else
         goto finish;

   address.sin_port   = htons(25);  // if 25 is blocked, then put the alternate smtp port 587 here
   address.sin_family = AF_INET;

   if ((smtpSocket = socket(AF_INET, SOCK_STREAM, 0)) != -1)
   {
      if (connect(smtpSocket, (struct sockaddr *)&address, sizeof(struct sockaddr_in)) != -1)
      {
         if ((smtpCode = doSMTPTransaction(smtpSocket, NULL, 0, transferBuffer)) > 299)
            goto closeSession;

         sendBufferSize = snprintf(transferBuffer, defaultBufferSize, "EHLO %s\r\n", argv[1]);
         if ((smtpCode = doSMTPTransaction(smtpSocket, transferBuffer, sendBufferSize, transferBuffer)) > 299)
            goto closeSession;

         sendBufferSize = sprintf(transferBuffer, "AUTH LOGIN\r\n");
         if ((smtpCode = doSMTPTransaction(smtpSocket, transferBuffer, sendBufferSize, transferBuffer)) > 334)
            goto closeSession;

         if ((smtpCode = doSMTPTransaction(smtpSocket, smtpAuthLoginID, strlen(smtpAuthLoginID), transferBuffer)) != 334)
            goto closeSession;

         if ((smtpCode = doSMTPTransaction(smtpSocket, smtpAuthPassword, strlen(smtpAuthPassword), transferBuffer)) != 235)
            goto closeSession;

         sendBufferSize = snprintf(transferBuffer, defaultBufferSize, "MAIL FROM:<%s>\r\n", argv[1]);
         if ((smtpCode = doSMTPTransaction(smtpSocket, transferBuffer, sendBufferSize, transferBuffer)) > 299)
            goto closeSession;

         for (i = 2; i < argc; i++)
         {
            sendBufferSize = snprintf(transferBuffer, defaultBufferSize, "RCPT TO:<%s>\r\n", argv[i]);
            if ((smtpCode = doSMTPTransaction(smtpSocket, transferBuffer, sendBufferSize, transferBuffer)) > 299)
               goto closeSession;
         }

         sendBufferSize = sprintf(transferBuffer, "DATA\r\n");
         if ((smtpCode = doSMTPTransaction(smtpSocket, transferBuffer, sendBufferSize, transferBuffer)) != 354)
            goto closeSession;

         while (c != EOF)
         {
            for (i = 0; i < defaultBufferSize && (c = fgetc(stdin)) != EOF; i++)
               transferBuffer[i] = c;
            smtpCode = doSMTPTransaction(smtpSocket, transferBuffer, i, NULL);
         }

         sendBufferSize = sprintf(transferBuffer, "\r\n.\r\nQUIT\r\n");
         if ((smtpCode = doSMTPTransaction(smtpSocket, transferBuffer, sendBufferSize, transferBuffer)) == 250);
            resultCode = 0;

      closeSession:
         close(smtpSocket);
      }
   }

finish:
   if (resultCode)
         syslog(LOG_ERR, "SMTPSend from %s to %s failed.", argv[1], argv[2]);

   return resultCode;
}
 
Back
Top