⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smtpio.c

📁 LINUX下的收发E-MAIL的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "smtpio.h"

static char *smtp_errlist[] = { "",
    ": prepare mail and server fail",
    ": Hostname failed to resolve",
    ": Socket failed to open",
    ": No route to host?",
    ": Server failed to acknowledge",
    ": HELO send()",
    ": HELO recv()",
    ": AUTH LOGIN auth()",
    ": AUTH USER auth()",
    ": AUTH PASSWORD auth()",
    ": MAIL FROM send()",
    ": MAIL FROM recv()",
    ": RCPT TO send()",
    ": RCPT TO recv()",
    ": DATA send()",
    ": DATA recv()",
    ": BODY recv()",
    ": RSET send()",
    ": RSET recv()",
    ": QUIT send()",
    ": QUIT recv()",
    ": Sender invalid",
    ": Recipient invalid"
};
extern int errno;
extern unsigned int emlTimeout;
SMTPError smtperrno;
extern Server smtpserver;
extern Email mymail;


char *smtpArror(void)
{
    return smtp_errlist[smtperrno];
}


int format_date(char *date, size_t date_size)
{
    time_t t;

    time(&t);
    if (strftime(date, date_size, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&t))
	== 0)
	return ERROR;
    else
	return SUCCESS;
}


int format_header(Email * msg)
{
// format the header information 
    char date[64], *hdrend;
    int hdrsize = 0, len;
    static Version smtpio_ver;

    smtpio_ver.part.major = VER_MAJOR;
    smtpio_ver.part.delim1 = '.';
    smtpio_ver.part.minor = VER_MINOR;
    smtpio_ver.part.delim2 = '.';
    smtpio_ver.part.release = VER_REL;
    smtpio_ver.part.null = '\0';

    format_date(date, 64);

// Create the header. 

    memset(msg->header, '\0', 320);

    hdrend = msg->header;

    hdrend += snprintf(msg->header, 64, "Date: %s\n", date);

    hdrend += snprintf(hdrend, 32, "From: %s\n", msg->from_addr);

    hdrend += snprintf(hdrend, 80, "To: %s\n", msg->to_addr);

    hdrend += snprintf(hdrend, 80, "Cc: %s\n", msg->cc_addr);

    hdrend += snprintf(hdrend, 64, "Subject: %s\n", msg->subject);

    if (msg->xmailer != NULL) {
	hdrend += snprintf(hdrend, 32, "X-Mailer: %s \n", msg->xmailer);
    }
    if (msg->mime_version != NULL) {
	hdrend +=
	    snprintf(hdrend, 32, "Mime-Version: %s\n", msg->mime_version);
    }
    if (msg->content_type != NULL) {
	hdrend +=
	    snprintf(hdrend, 64, "Content-Type: %s\n", msg->content_type);
    }
    if (msg->content_transfer_encoding != NULL) {
	hdrend +=
	    snprintf(hdrend, 64, "Content-Transfer-Encoding: %s\n",
		     msg->content_transfer_encoding);
    }

    return SUCCESS;
}


int eml_smtp_helo(int sock)
{
    // say hello to the server 
    char buffer[256];
    char command[40];
    char localhost[MAXHOSTNAMELEN];
    int len, ok = 0;

//      get the localhost name 
    gethostname(localhost, MAXHOSTNAMELEN);

//      hiya server! how are you today? 
    snprintf(command, 255, "HELO %s\r\n", localhost);
    if (send(sock, command, strlen(command), 0) < 0) {
	smtperrno = S_ERR_HELO_SEND;
	return ERROR;
    }

    if (((len = recvline(sock, buffer, 255)) < 0)
	|| ((ok = find_string(buffer, ReqMlActOK)) == -1)) {
	smtperrno = S_ERR_HELO_RECV;
	if (ok < 0 && len > 0)	// if we got a response, even tho it didn't    
	{			// like it, lets ignore it and continue anyway 
	    fprintf(stderr,
		    "Warning: smtp server did not like our HELO.\n");
	    return SUCCESS;
	}
	return ERROR;		// it failed to respond at all, so fuck it 
    }
    return SUCCESS;
}


int eml_smtp_auth(int sock, char *username, char *password)
{
    char buffer[256];
    char buffer1[256];
    char command[30];
    int n = 0;
    int len = 0;
    strncpy(command, "AUTH LOGIN\r\n", 255);

    if (send(sock, command, strlen(command), 0) < 0) {
	smtperrno = S_ERR_AUTH_LOGIN;
	return ERROR;
    }

    if ((recvline(sock, buffer, 255) < 0)
	|| (find_string(buffer, AuthLoginCon) == -1)) {
	smtperrno = S_ERR_AUTH_LOGIN;
	return ERROR;
    }

    n = strlen(username);
    strcpy(buffer1, eml_mime_encode_base64(username, &n, 1));

    len = strlen(buffer1);
    *(buffer1 + len - 1) = 0;

    len = strlen(buffer1);
    snprintf(command, n + 3, "%s\r\n", buffer1);

    if (send(sock, command, strlen(command), 0) < 0) {
	smtperrno = S_ERR_AUTH_USER;
	return ERROR;
    }

    if ((recvline(sock, buffer, 255) < 0)
	|| (find_string(buffer, AuthLoginCon) == -1)) {
	smtperrno = S_ERR_AUTH_USER;
	return ERROR;
    }

    n = strlen(password);
    strcpy(buffer1, eml_mime_encode_base64(password, &n, 1));

    len = strlen(buffer1);
    *(buffer1 + len - 1) = 0;

    len = strlen(buffer1);
    snprintf(command, n + 3, "%s\r\n", buffer1);

    if (send(sock, command, strlen(command), 0) < 0) {
	smtperrno = S_ERR_AUTH_PASSWORD;
	return ERROR;
    }

    if ((recvline(sock, buffer, 255) < 0)
	|| (find_string(buffer, AuthLoginOK) == -1)) {
	smtperrno = S_ERR_AUTH_PASSWORD;
	return ERROR;
    }

    return SUCCESS;
}


int eml_smtp_mail(int sock, const char *sender)
{
    int reply, iffind;
    // we gotta tell the smtp server who we are. (our email addy) 
    char buffer[256];
    char command[46];

    snprintf(command, 255, "MAIL FROM:%s\r\n", sender);
    if (send(sock, command, strlen(command), 0) < 0) {
	smtperrno = S_ERR_MAIL_SEND;
	return ERROR;
    }
    if (((reply = recvline(sock, buffer, 255)) < 0)
	|| (iffind = (find_string(buffer, ReqMlActOK)) == -1)) {
	// we should have gotten a message from the smtp server saying:
	// 250 user@host.com... Sender ok
	smtperrno = S_ERR_MAIL_RECV;
	return ERROR;
    }
    return SUCCESS;
}


int eml_smtp_rcpt(int sock, char *recipient, char *orig_rcpt)
{
    // we gotta tell the smtp server who we are going to be sending
    // our email to 
    static char buffer[256];
    static char command[102];

#undef I_KNOW_WHAT_ORCPT_IS_FOR
#ifdef I_KNOW_WHAT_ORCPT_IS_FOR
    if (orig_rcpt == (gchar *) NULL || strcmp(recipient, orig_rcpt) == 0)
	// No original recipient specified or same as recipient. 
	snprintf(command, 511, "RCPT TO: %s\r\n", recipient);
    else
	snprintf(command, 511, "RCPT TO: %s ORCPT=%s\r\n", recipient,
		 orig_rcpt);
#else
    snprintf(command, 511, "RCPT TO: %s\r\n", recipient);
#endif

    if (send(sock, command, strlen(command), 0) < 0) {
	smtperrno = S_ERR_RCPT_SEND;
	return ERROR;
    }

    if ((recvline(sock, buffer, 255) < 0)
	|| (find_string(buffer, ReqMlActOK) == -1)) {
	// we should have gotten a message from the smtp server saying:
	// 250 user@host.com... Recipient ok
	smtperrno = S_ERR_RCPT_RECV;
	return ERROR;
    }
//printf("RCPT TO SUCCESS\n");
    return SUCCESS;
}


int eml_smtp_data(int sock, char *header, char *body)
{
    // now we can actually send what's important :p 
    char buffer[256];
    char command[8];
    char data[6];
    int i;

    strncpy(command, "DATA\r\n", 255);
    if (send(sock, command, strlen(command), 0) < 0) {
	smtperrno = S_ERR_DATA_SEND;
	return ERROR;
    }
    if ((recvline(sock, buffer, 255) < 0)
	|| (find_string(buffer, StrtMailInpt) == -1)) {
	// we should have gotten instructions on how to use the DATA command:
	// 354 Enter mail, end with "." on a line by itself
	smtperrno = S_ERR_DATA_RECV;
	return ERROR;
    }
    // now to send the actual data 
    // send the header information

//      for (i = 0; i < strlen(header); i++)
    for (i = 0; i < 320; i++) {
	if (header[i] == '\n' && header[i + 1] == '\0')
	    break;

	if (header[i] == '\n')
	    strncpy(data, "\r\n", 3);
	else
	    snprintf(data, 3, "%c", header[i]);
	send(sock, data, strlen(data), 0);
    }
    send(sock, "\r\n\r\n", 4, 0);


// send the body of the message 
    for (i = 0; i < strlen(body); i++) {
	if (body[i] == '.' && body[i - 1] == '\n' && body[i + 1] == '\n') {
	    // if we have a lone period on a line... 
	    strcpy(data, "..");
	} else if (body[i] == '\n' && body[i - 1] != '\r') {
	    strcpy(data, "\r\n");
	} else {
	    data[0] = body[i];
	    data[1] = '\0';
	}
	send(sock, data, strlen(data), 0);
    }
//      terminate the message body 
    send(sock, "\r\n.\r\n", 5, 0);

    if ((recvline(sock, buffer, 255) < 0)
	|| (find_string(buffer, ReqMlActOK) == -1)) {
	// Should've gotten a respose saying our message is ready for delivery
	smtperrno = S_ERR_BODY_RECV;
	return ERROR;
    }
    return SUCCESS;
}


int eml_smtp_rset(int sock)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -