免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3405 | 回复: 4
打印 上一主题 下一主题

[C] 邮件发送程序 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-01-27 09:51 |只看该作者 |倒序浏览
本帖最后由 darkce 于 2010-02-21 15:35 编辑

邮件发送程序。
64位代码转换有错,已经更正,见4楼。


//libmail.h
int authmail(char *addr, int port, char *name, char *pwd);
int sendmail(int fd, char *from, char *title, char *to, char *msg);





// libmail.cpp
#include "libmail.h"


void enbase64(char *dst, const char *src, int len);

/***
  建立一个连接并进行认证

  errno 500                        创建 socket 失败
  errno 501                        端口打开失败
  errno 502                        认证失败
*******************************************************/
int authmail(char *addr, int port, char *name, char *pwd)
{
        int fd;
        fd = socket(PF_INET, SOCK_STREAM, 0);
        if (fd == -1 ) {
                errno = 500;
                return -1;
        }

    long timeout = 15000;
    setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
    setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));

        char *ip;
        struct hostent *h;
        h = gethostbyname(addr);
        ip = inet_ntoa(*((struct in_addr*)h->h_addr));

        struct sockaddr_in to;
        memset(&to, '\0', sizeof(to));
        to.sin_family = PF_INET;
        to.sin_port = htons(port);
        to.sin_addr.s_addr = inet_addr(ip);

        int ret;
        ret = connect(fd, (struct sockaddr*)&to, sizeof(struct sockaddr));
        if (ret == -1) {
                closesocket(fd);
                errno = 501;
                return ret;
        }

        /* login */
        char buf[4096];
        int icou;
        icou = recv(fd, buf, sizeof(buf), 0);
        buf[icou+1] = '\0';

        /* auth login */
        icou = send(fd, "AUTH LOGIN\r\n", strlen("AUTH LOGIN\r\n"), 0);

        icou = recv(fd, buf, sizeof(buf), 0);
        buf[icou+1] = '\0';

        if (atoi(buf) == 334) {
                /* send user name */
                enbase64(buf, name, strlen(name));
                sprintf(buf, "%s\r\n", buf);
                icou = send(fd, buf, strlen(buf), 0);
               
                icou = recv(fd, buf, sizeof(buf), 0);
                buf[icou+1] = '\0';
                if (atoi(buf) == 334) {
                        /* send user pwd */
                        enbase64(buf, pwd, strlen(pwd));
                        sprintf(buf, "%s\r\n", buf);
                        icou = send(fd, buf, strlen(buf), 0);

                        icou = recv(fd, buf, sizeof(buf), 0);
                        buf[icou+1] = '\0';
                        if (atoi(buf) == 235) { return fd; }
                }
        }

        errno = 502;
        return -1;
}


int sendmail(int fd, char *from, char *title, char *to, char *msg)
{
        char buf[4096];
        int icou;

        /* MAIL FROM */
        sprintf(buf, "MAIL FROM: <%s>\r\n", from);
        send(fd, buf, strlen(buf), 0);

        icou = recv(fd, buf, sizeof(buf), 0);
        buf[icou+1] = '\0';
        if (atoi(buf) != 250) { return -1; }
       

        /* RCPT TO */
        char *pa = to;
        char *p;
        while (*pa) {
                p = buf;
                p += sprintf(p, "RCPT TO: <");
                while (!(*pa == ';' || *pa == '\0')) {
                        *p++ = *pa++;
                }
                *p++ = '>';
                *p++ = '\r';
                *p++ = '\n';
                *p++ = '\0';


                send(fd, buf, strlen(buf), 0);
                icou = recv(fd, buf, sizeof(buf), 0);
                buf[icou+1] = '\0';
                if (atoi(buf) != 250) { return -1; }

                pa++;
        }


        /* DATA */
        send(fd, "DATA\r\n", strlen("DATA\r\n"), 0);

        icou = recv(fd, buf, sizeof(buf), 0);
        buf[icou+1] = '\0';
        if (atoi(buf) != 354) { return -1; }

        /* MIME DATA */
        pa = to;
        p = buf;
        p += sprintf(p, "From: <%s>\r\n", from);
        p += sprintf(p, "To: <");
        while (*pa) {
                if (*pa == ';') {
                        *p++ = '>';
                        *p++ = ',';
                        *p++ = '\r';
                        *p++ = '\n';
                        *p++ = '\t';
                        *p++ = '<';
                        pa++;
                } else {
                        *p++ = *pa++;
                }
        }
        *p++ = '>';
        *p++ = '\r';
        *p++ = '\n';
        p += sprintf(p, "Subject: <%s>\r\nContent-Type: text/plain; \r\n\r\n %s\r\n.\r\n", title, msg);


        printf("%s", buf);
        icou = send(fd, buf, strlen(buf), 0);
        icou = recv(fd, buf, sizeof(buf), 0);
        buf[icou+1] = '\0';
        if (atoi(buf) != 250) { return -1; }

        send(fd, "QUIT\r\n", strlen("QUIT\r\n"), 0);
        icou = recv(fd, buf, sizeof(buf), 0);
        buf[icou+1] = '\0';
        if (atoi(buf) != 221) { return -1; }
        return 0;
}


void enbase64(char *dst, const char *src, int len)
{
        int i=0;
        char map64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

        for (; i<len-len%3; i+=3) {
                *dst++ = map64[(src>>2) & 0x3F];
                *dst++ = map64[((src<<4) & 0x30) + ((src[i+1]>>4) & 0xF)];
                *dst++ = map64[((src[i+1]<<2) & 0x3C) + ((src[i+2]>>6) &0x3)];
                *dst++ = map64[src[i+2] & 0x3F];
        }

        if (len%3 == 1) {
                *dst++ = map64[(src>>2) & 0x3F];
                *dst++ = map64[(src<<4) & 0x30];
                *dst++ = '=';
                *dst++ = '=';
        }

        if (len%3 == 2) {
                *dst++ = map64[(src>>2) & 0x3F];
                *dst++ = map64[(src<<4) & 0x30 + ((src[i+1]>>4) & 0xF)];
                *dst++ = map64[(src<<2) & 0x3C];
                *dst++ = '=';
        }

        *dst = '\0';
}

论坛徽章:
0
2 [报告]
发表于 2010-01-27 11:04 |只看该作者

论坛徽章:
0
3 [报告]
发表于 2010-01-27 17:59 |只看该作者

论坛徽章:
0
4 [报告]
发表于 2010-02-21 15:34 |只看该作者
64位代码转换有错, 更正。如下
// b64.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <string.h>


static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";
void encodeblock( unsigned char in[3], unsigned char out[4], int len )
{
    out[0] = cb64[ in[0] >> 2 ];
    out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
    out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=');
    out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '=');
}

void encode(const char *in, char *out);
void encode(const char *instr, char *outstr)
{
    unsigned char in[3], out[4];
    int i, len, blocksout = 0;

    while(*instr)
        {
        len = 0;
               
                memset(in, '\0', 3);
        for( i = 0; i < 3; i++ )
                {
                        if (*instr)
                        {
                                in[i] = (unsigned char)*instr++;
                                len++;
                        }
        }

        if( len )
                {
            encodeblock( in, out, len );
            for( i = 0; i < 4; i++ )
                        {
                                *outstr++ = out[i];
            }
        }
    }
}


int main(int argc, char* argv[])
{
        char *src="huangchao@zhongsou.com";
        char buf[1024];

        memset(&buf, '\0', sizeof(buf));
        encode(src, buf);
        printf("%s\r\n", buf);

        printf("Hello World!\n");
        return 0;
}

论坛徽章:
0
5 [报告]
发表于 2010-02-21 15:39 |只看该作者
收藏一下。发垃圾邮件。。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP