C语言编写smtp用户代理之协议操作

来源:互联网 发布:阿里云邮箱前缀怎么写 编辑:程序博客网 时间:2024/05/18 01:58

上一章写了socket 操作,这一章用上一章的内容写smtp协议相关操作的函数。
首先是smtp.h文件

#ifndef SMTP_H#define SMTP_H#include"renyj_sock.h"//根据smtp协议,用来处理发送和接收EHLO的函数int mail_say_hello(char *hello_domain);//用来处理FROM命令和接受其回复的函数int mail_from(char *from);//用来处理RCPT TO命令和接收其回复的函数int mail_to(char *to);//用来处理DATA 命令和接收其回复的函数int mail_data();//用来处理QUIT命令和接收其回复的函数int mail_quit();//用来处理发送 . 和接收其回复的函数int mail_eom();//用来处理用户认证的函数int mail_auth(char *uer,char *pass);//用来发送邮件的函数int send_the_mail(char *from,char *to,char *server,int port,char *user,                        char *pass,char *subject,char *msgline,int timeout);#endif

二、函数实现,smtp.c文件。

#include"smtp.h"#include"mutils.h"char mail_buff[1000] = "";//用来读取邮件服务器回复的函数int smtp_read_line(){    memset(mail_buff,0x00,sizeof(mail_buff));    int rc = mysock_gets(mail_buff,100,10);    if (rc < 0)    {        return rc;    }    debug("[S] -----> %s",mail_buff);    return rc;}/*处理EHLO函数,这里我发现需要向服务器发送两次EHLO命令,可能时跟服务器有关系。如果有清楚的大神还请指点一下。我这样写是根据实际情况自己分析出来的。*/int mail_say_hello(char *hello_domain){    memset(mail_buff,0x00,sizeof(mail_buff));    mysock_puts("EHLO ");    int rc = smtp_read_line();    sprintf(mail_buff,"EHLO %s\r\n",hello_domain);    mysock_puts(mail_buff);    do    {    rc = smtp_read_line();    if (rc < 0)    {        debug("say hello error");        return -1;    }    }while(NULL != strstr(mail_buff,"-"));}//处理FROM命令int mail_from(char *from){    memset(mail_buff,0x00,sizeof(mail_buff));    sprintf(mail_buff,"MAIL FROM: <%s>\r\n",from);    mysock_puts(mail_buff);    memset(mail_buff,0x00,sizeof(mail_buff));    int rc = smtp_read_line();    if (rc<0)    {        debug("rcv mail from error");        return -1;    }}//处理TO命令int mail_to(char *to){    memset(mail_buff,0x00,sizeof(mail_buff));    sprintf(mail_buff,"RCPT TO: <%s>\r\n",to);    mysock_puts(mail_buff);    memset(mail_buff,0x00,sizeof(mail_buff));    int rc = smtp_read_line();    if (rc<0)    {        debug("rcv mail to error");        return -1;    }}//处理DATA命令。int mail_data(){    memset(mail_buff,0x00,sizeof(mail_buff));    mysock_puts("DATA\r\n");        int rc = smtp_read_line();    if (rc < 0)    {        debug("rcv data error");        return -1;    }}//发送 . 来让邮件结束输入int mail_eom(){    mysock_puts("\r\n.\r\n");    smtp_read_line();}//退出邮件int mail_quit(){    mysock_puts("QUIT\r\n");    smtp_read_line();}//邮件的认证int mail_auth(char *user,char *pass){    char *b64 = NULL;    char buf[1000]="";    //发送LOGIN认证,因为是针对qq服务器,我知道它支持这个。    mysock_puts("AUTH LOGIN\r\n");    int rc = smtp_read_line();    if (rc < 0)    {        debug("auth login rcv error");        return -1;    }    memset(mail_buff,0x00,sizeof(mail_buff));    //这里需要对用户名进行base64的加密。不一定非要用这个函数,如果有人要用,我会上传源码    b64=mutils_encode_base64_noformat(user,strlen(user));    if (b64 == NULL)    {        debug("Could not base64 encode user: %s",user);        return -1;    }    memset(buf,0,sizeof(buf));    (void) snprintf(buf,sizeof(buf)-1,"%s\r\n",b64);    mysock_puts(buf);    memset(mail_buff,0x00,sizeof(mail_buff));    rc = smtp_read_line();    if (rc < 0)    {        debug("user error");        return -1;    }    //这里需要对用户名进行base64的加密    b64=mutils_encode_base64_noformat(pass,strlen(pass));    if (b64 == NULL)    {        debug("Could not base64 encode passworf of user: %s",pass);        return -1;    }    memset(buf,0,sizeof(buf));    (void) snprintf(buf,sizeof(buf)-1,"%s\r\n",b64);    mysock_puts(buf);    memset(mail_buff,0x00,sizeof(mail_buff));    rc = smtp_read_line();    if (rc < -1)    {        debug("pass error");        return -1;    }}int send_the_mail(char *from,char *to,char *server,int port,char *user,                                char *pass,char *subject,char *msgline,int timeout){    //init the client socket    int rc;     rc = myclient_sock(0,server,port,timeout);    if (rc < 0)    {        debug("myclient_sock error");        return -1;    }    set_socket(rc);    //turn on the ssl    char *cip = NULL;    openssl_init(cip);    turn_on_ssl(get_socket());    //say ehlo      char *hello_domain = "localhost";    mail_say_hello(hello_domain);    //use login,and start AUTH    debug("start AUTH");    mail_auth(user,pass);    //FROM     debug("start FROM");    mail_from(from);        //TO    debug("start TO");    mail_to(to);    //DATA    debug("start DATA");    mail_data();    //send the Subject      char subjectbuff[150] = "";    //这里就是标题内容    sprintf(subjectbuff,"Subject: %s\r\n",subject);    //from可能必须按照你登录的账号填写,要不然就会被当做垃圾邮件    mysock_puts("From: xxxxxx@qq.com\r\n");    mysock_puts("Date:\r\n");    mysock_puts("To: xxxxxx@qq.com\r\n");    mysock_puts(subjectbuff);    //这里content-type必须写,要不然发出去的就不知道什么类型了,也不会吧你发的那句话当做消息。    mysock_puts("Content-type: text/plain\r\n\r\n");    mysock_puts(msgline);    //use . end data     debug("start eom");    mail_eom();    //quit the msg    debug("QUIT");    mail_quit();    mysock_close();    return 0;}
原创粉丝点击