📄 sflmail.c
字号:
/* ----------------------------------------------------------------<Prolog>-
Name: sflmail.c
Title: SMTP mailer functions
Package: standard function library (sfl)
Written: 1997/06/18 Scott Beasley <jscottb@infoave.com>
Revised: 2000/01/19 iMatix SFL project team <sfl@imatix.com>
Synopsis: Functions to format and send SMTP messages. Messages
can contain attachments, and be sent with "cc"'s "bcc"'s as
well as the normal "to" receivers.
Copyright: Copyright (c) 1996-2000 iMatix Corporation
License: this is free software; you can redistribute it and/or modify
it under the terms of the sfl license agreement as provided
in the file license.txt. this software is distributed in
the hope that it will be useful, but without any warranty.
------------------------------------------------------------------</Prolog>-*/
#include "prelude.h" /* Universal header file */
#include "sflstr.h"
#include "sflsock.h"
#include "sfldate.h"
#include "sflmime.h"
#include "sflprint.h" /* snprintf functions */
#include "sflmail.h"
/* Macros & defines */
/* Macro to encoding a char and make it printable. */
#define ENC(c) ((c) ? ((c) & 077) + ' ': '`')
/* Macro to write too the smtp port. */
#define smtp_send_data(sock,strout) write_TCP((sock),(strout),strlen((strout)))
/* Stactic function prototypes */
static int uuencode (char *strin, char *strout, char *last_smtp_message);
static void putgroup (register char *strgroup, register FILE *fp);
static int getreply (int iSocket, SMTP *smtp);
static char *getfilename (char *strfullpath);
/* ---------------------------------------------------------------------[<]-
Function: smtp_send_mail_ex
Synopsis: Format and send a SMTP message. This function gives you the
options of sneding to multi receivers, CC's, Bcc's and also send
UUencoded attachments. Receivers and files are ";" or "," terminated.
NOTE: The sock_init function should be called before use of this
function.
---------------------------------------------------------------------[>]-*/
int smtp_send_mail_ex (
SMTP *smtp)
{
FILE *fpin;
int iCnt;
sock_t iSocket;
char strOut[514], strFile[256], strRetBuff[513];
char strUUEFile[256], *strRcptUserIds;
int iOld_ip_nonblock = ip_nonblock, rcptUserIdsLen;
/* Make sure we block on socket accesses */
ip_nonblock = FALSE;
/* Open up the SMTP port (25 most of the time). */
iSocket = connect_socket (smtp->strSmtpServer,
"smtp", "tcp", NULL,
smtp->connect_retry_cnt,
smtp->retry_wait_time);
if (getreply (iSocket, smtp) > 400 || iSocket < 0)
return -1;
/* Format a SMTP meassage header. */
/* Just say hello to the mail server. */
xstrcpy (strOut, "HELO ", get_hostname (), "\n", NULL);
smtp_send_data (iSocket, strOut);
if (getreply (iSocket, smtp) > 400)
return -2;
/* Tell the mail server who the message is from. */
xstrcpy (strOut, "MAIL FROM:<", smtp->strSenderUserId, ">\n", NULL);
smtp_send_data (iSocket, strOut);
if (getreply (iSocket, smtp) > 400)
return -3;
rcptUserIdsLen = (strlen (smtp->strDestUserIds) +
strlen (smtp->strCcUserIds) +
strlen (smtp->strBccUserIds) + 3);
strRcptUserIds = (char *) malloc (rcptUserIdsLen);
snprintf (strRcptUserIds, rcptUserIdsLen, "%s;%s;%s",
smtp->strDestUserIds, smtp->strCcUserIds, smtp->strBccUserIds);
/* The following tells the mail server who to send it to. */
iCnt = 0;
while (1)
{
getstrfld (strRcptUserIds, iCnt++, 0, ",;", strRetBuff);
if (*strRetBuff)
{
xstrcpy (strOut, "RCPT TO:<", strRetBuff, ">\r\n", NULL);
smtp_send_data (iSocket, strOut);
if (getreply (iSocket, smtp) > 400)
return -4;
}
else
break;
}
free (strRcptUserIds);
/* Now give it the Subject and the message to send. */
smtp_send_data (iSocket, "DATA\r\n");
if (getreply (iSocket, smtp) > 400)
return -5;
/* Set the date and time of the message. */
xstrcpy ( strOut, "Date: ", encode_mime_time (date_now (), time_now ()),
" \r\n", NULL );
/* The following shows all who it was sent to. */
if ( smtp->strFullDestUserIds && *smtp->strFullDestUserIds )
{
replacechrswith (smtp->strFullDestUserIds, ";", ',');
xstrcpy (strOut, "To: ", smtp->strFullDestUserIds, "\r\n", NULL);
}
else
{
replacechrswith (smtp->strDestUserIds, ";", ',');
xstrcpy (strOut, "To: ", smtp->strDestUserIds, "\r\n", NULL);
}
/* Set up the Reply-To path. */
if (!smtp->strRetPathUserId || !*smtp->strRetPathUserId)
smtp->strRetPathUserId = smtp->strSenderUserId;
if ( strstr( smtp->strRetPathUserId, "<" ) != NULL &&
strstr( smtp->strRetPathUserId, ">" ) != NULL )
{
xstrcat (strOut, "Reply-To:", smtp->strRetPathUserId, "\r\n", NULL);
}
else
{
xstrcat (strOut, "Reply-To:<", smtp->strRetPathUserId, ">\r\n", NULL);
}
if ( smtp->strFullSenderUserId && *smtp->strFullSenderUserId )
{
xstrcat (strOut, "Sender:", smtp->strFullSenderUserId, "\r\n", NULL);
xstrcat (strOut, "From:", smtp->strFullSenderUserId, "\r\n", NULL);
}
else
{
xstrcat (strOut, "Sender:", smtp->strSenderUserId, "\r\n", NULL);
xstrcat (strOut, "From:", smtp->strSenderUserId, "\r\n", NULL);
}
smtp_send_data (iSocket, strOut);
*strOut = '\0';
/* Post any CC's. */
if (smtp->strFullCcUserIds && *smtp->strFullCcUserIds)
{
replacechrswith (smtp->strFullCcUserIds, ";", ',');
xstrcat (strOut, "Cc:", smtp->strFullCcUserIds, "\r\n", NULL );
}
else
if (smtp->strCcUserIds && *smtp->strCcUserIds)
{
replacechrswith (smtp->strCcUserIds, ";", ',');
xstrcat (strOut, "Cc:", smtp->strCcUserIds, "\r\n", NULL );
}
/* Post any BCC's. */
if (smtp->strFullBccUserIds && *smtp->strFullBccUserIds)
{
replacechrswith (smtp->strFullBccUserIds, ";", ',');
xstrcat (strOut, "Bcc:", smtp->strFullBccUserIds, "\r\n", NULL);
}
else
if (smtp->strBccUserIds && *smtp->strBccUserIds)
{
replacechrswith (smtp->strBccUserIds, ";", ',');
xstrcat (strOut, "Bcc:", smtp->strBccUserIds, "\r\n", NULL);
}
/* Post any Return-Receipt-To. */
if (smtp->strRrcpUserId && *smtp->strRrcpUserId)
xstrcat (strOut, "Return-Receipt-To:", smtp->strRrcpUserId, ">\r\n",
NULL);
if (smtp->strMailerName && *smtp->strMailerName)
xstrcat (strOut, "X-Mailer: ", smtp->strMailerName, "\r\n", NULL);
else
strcat (strOut, "X-Mailer: sflmail function\r\n");
/* Set the mime version. */
strcat (strOut, "MIME-Version: 1.0\r\n");
strcat (strOut,
"Content-Type: Multipart/Mixed; boundary=Message-Boundary-21132\r\n");
smtp_send_data (iSocket, strOut);
/* Write out any message comment included. */
xstrcpy (strOut, "Comments: ", smtp->strMsgComment, "\r\n", NULL);
/* Send the subject and message body. */
xstrcat (strOut, "Subject:", smtp->strSubject, "\n\r\n", NULL);
smtp_send_data (iSocket, strOut);
/* Keep rfc822 in mind with all the sections. */
if (smtp->strMessageBody && *smtp->strMessageBody)
{
strcat (strOut, "\r\n--Message-Boundary-21132\r\n");
strcat (strOut, "Content-Type: text/plain; charset=US-ASCII\r\n");
strcat (strOut, "Content-Transfer-Encoding: 7BIT\r\n");
strcat (strOut, "Content-description: Body of message\r\n\r\n");
smtp_send_data (iSocket, strOut);
smtp_send_data (iSocket, smtp->strMessageBody);
smtp_send_data (iSocket, "\r\n");
}
/* Include any Text type files and Attach them to the message. */
if (smtp->strTxtFiles && *smtp->strTxtFiles)
{
iCnt = 0;
while (1)
{
getstrfld (smtp->strTxtFiles, iCnt++, 0, ",;", strFile);
trim (strFile);
if (*strFile)
{
fpin = fopen (strFile, "rb");
if (!fpin)
{
strcpy (smtp->strlast_smtp_message, strFile);
return -6;
}
strcpy (strOut, "\r\n--Message-Boundary-21132\r\n");
strcat (strOut,
"Content-Type: text/plain; charset=US-ASCII\r\n");
strcat (strOut, "Content-Transfer-Encoding: 7BIT\r\n");
xstrcat (strOut, "Content-Disposition: attachment; filename=",
getfilename (strFile), "\r\n\n", NULL);
smtp_send_data (iSocket, strOut);
while (!feof (fpin))
{
memset (strRetBuff, 0, 513);
fread (strRetBuff, sizeof (char), 512, fpin);
smtp_send_data (iSocket, strRetBuff);
}
fclose (fpin);
}
else
break;
}
}
/* Attach any bin files to the message. */
if (smtp->strBinFiles && *smtp->strBinFiles)
{
iCnt = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -