As we all know, to send an email is to write an SMTP client. SMTP is actually based on the anscii character Protocol. To put it bluntly, that is, you send the specified character to the server, the server will have a corresponding response. Of course, what characters will the server send? This is the SMTP protocol.
If you want to send binary files and audio and video data, you need mime (universal Internet Mail extended Protocol). It uses some encoding methods to convert the data into anscii characters and send them out, the acceptor uses the corresponding decoding method for decoding.
Here we create a simple mail sending program, in which the authentication adopts base64 encoding, which divides the data stream into 24-bit blocks and then converts the 24-bit to 4-6 characters, the base64 encoding character.
1. Of course, it is to connect to the SMTP server, TCP connection to port 25 of the server
2. log on to the server, send "ehlo localhost/R/N", "auth login/R/N" ", and send the base64-encoded Username
The base64-encoded password is sent and ends with "/R/N ".
3. Send an email
4. Exit
Source program attached:
/*
Funtion: Send email
Author: liyanan
Data: 2006-08 8
*/
# Include <stdlib. h>
# Include <stdio. h>
# Include <string. h>
# Include <netdb. h>
# Include <sys/types. h>
# Include <sys/STAT. h>
# Include <unistd. h>
# Include <fcntl. h>
# Include <sys/IOCTL. h>
# Include <netinet/in. h>
# Include <sys/socket. h>
# Include <Linux/if_ether.h>
# Include <net/If. h>
# Include <errno. h>
# Define eth_name "eth0"
# Define sd_both 2
# Define socket_error-1
# Define invalid_socket-1
Int S;
Struct sockaddr_in remote;
Unsigned short port;
Int RT;
Char * send_data;
Char * recv_data;
Char * hostname;
Struct hostent * HT;
Char * usersrc, * userdes, * passsrc, * passdes;
Char * From, * to, * Date, * subject;
Char * filename;
Int getlocaladdress (char * szipaddr)
{
Int sock;
Struct sockaddr_in sin;
Struct sockaddr SA;
Struct ifreq IFR;
Sock = socket (af_inet, sock_dgram, 0 );
If (sock =-1)
{
Printf ("error: Get local IP socket fail! /N ");
Return-1;
}
Strncpy (IFR. ifr_name, eth_name, ifnamsiz );
IFR. ifr_name [ifnamsiz-1] = 0;
If (IOCTL (sock, siocgifaddr, & IFR) <0)
{
Printf ("error: Get local ip ioctl fail! ");
Return-1;
}
Memcpy (& sin, & IFR. ifr_addr, sizeof (SIN ));
Sprintf (szipaddr, "% s", inet_ntoa (SIN. sin_addr ));
Return 0;
}
Int getlocalmac (unsigned char * vmac)
{
Int sock;
Int I;
Struct sockaddr_in sin;
Struct sockaddr SA;
Struct ifreq IFR;
Unsigned char Mac [6];
Sock = socket (af_inet, sock_dgram, 0 );
If (sock =-1)
{
Perror ("socket ");
Return-1;
}
Strncpy (IFR. ifr_name, eth_name, ifnamsiz );
IFR. ifr_name [ifnamsiz-1] = 0;
Memset (MAC, 0, sizeof (MAC ));
If (IOCTL (sock, siocgifhwaddr, & IFR) <0)
{
Perror ("IOCTL ");
Return-1;
}
Memcpy (& SA, & IFR. ifr_addr, sizeof (SIN ));
Memcpy (MAC, SA. sa_data, 6 );
Sprintf (vmac, "%. 2x: %. 2x: %. 2x: %. 2x: % 0.2x: % 0.2x/N ", Mac [0], Mac [1], Mac [2], Mac [3], Mac [4], mac [5]);
Return 0;
}
Void destory ()
{
If (s! = Invalid_socket)
{
Shutdown (S, sd_both );
Close (s );
// Wsacleanup ();
}
Free (from );
Free ();
Free (date );
Free (subject );
Free (filename );
Free (recv_data );
Free (userdes );
Free (passdes );
}
Void base64_code (unsigned char * chsrc, unsigned char * chdes)
{
Char Chadd [3];
Unsigned char temp [4], T;
Int Len, I;
Len = strlen (char *) chsrc );
While (LEN> = 3)
{
Temp [0] = (* chsrc)> 2;
T = (* chsrc & 0x03) <4;
Temp [1] = (* (chsrc + 1)> 4) | T;
T = (* (chsrc + 1) <2) & 0x3f );
Temp [2] = (* (chsrc + 2)> 6) | T;
Temp [3] = (* (chsrc + 2) & 0x3f );
For (I = 0; I <4; I ++)
{
If (temp [I]> = 0 & temp [I] <= 25)
* (Chdes + I) = temp [I] + 65;
If (temp [I]> = 26 & temp [I] <= 51)
* (Chdes + I) = temp [I] + 71;
If (temp [I]> = 52 & temp [I] <= 61)
* (Chdes + I) = temp [I]-4;
If (temp [I] = 62)
* (Chdes + I) = 43;
If (temp [I] = 63)
* (Chdes + I) = 47;
}
Len-= 3;
Chsrc + = 3;
Chdes + = 4;
}
If (Len! = 0)
{
For (I = 0; I <3; I ++)
Chadd [I] = 0;
Memcpy (Chadd, chsrc, Len );
Temp [0] = Chadd [0]> 2;
T = (Chadd [0] & 0x03) <4;
Temp [1] = (Chadd [1]> 4) | T;
T = (Chadd [1] <2) & 0x3f );
Temp [2] = (Chadd [2]> 6) | T;
Temp [3] = Chadd [2] & 0x3f;
For (I = 0; I <4; I ++)
{
If (temp [I]> = 0 & temp [I] <= 25 & (I = 0 | I = 1) * (chdes + I) = temp [I] + 65;
Else * (chdes + I) = 61;
If (temp [I]> = 26 & temp [I] <= 51) * (chdes + I) = temp [I] + 71;
Else if (temp [I]> = 52 & temp [I] <= 61) * (chdes + I) = temp [I]-4;
Else if (temp [I] = 62) * (chdes + I) = 43;
Else if (temp [I] = 63) * (chdes + I) = 47;
}
Chdes + = 4;
* Chdes = '/0 ';
Return;
}
* Chdes = '/0 ';
}
Void base64_decode (unsigned char * chsrc, unsigned char * chdes)
{
Unsigned char temp [4], T;
Int Len, I;
Len = strlen (char *) chdes );
While (LEN> = 4)
{
For (I = 0; I <4; I ++)
{
If (* (chdes + I)> = 65 & * (chdes + I) <= 90)
Temp [I] = * (chdes + I)-65;
If (* (chdes + I)> = 97 & * (chdes + I) <= 122)
Temp [I] = * (chdes + I)-71;
If (* (chdes + I)> = 48 & * (chdes + I) <= 57)
Temp [I] = * (chdes + I) + 4;
If (* (chdes + I) = 43)
Temp [I] = 62;
If (* (chdes + I) = 47)
Temp [I] = 63;
If (* (chdes + I) = 61)
Temp [I] = 0;
}
T = (temp [1]> 4) & 0x03;
* Chsrc = (temp [0] <2) | T;
T = (temp [2]> 2) & 0x0f;
* (Chsrc + 1) = (temp [1] <4) | T;
T = temp [3];
* (Chsrc + 2) = (temp [2] <6) | T;
Chsrc + = 3;
Chdes + = 4;
Len-= 4;
}
Chsrc-= 3;
For (I = 0; I <3; I ++)
{
If (* (chsrc + I) = 0)
{
* (Chsrc + I) = '/0 ';
Break;
}
}
If (I> = 2)
* (Chsrc + 3) = '/0 ';
}
Int getresponse ()
{
RT = Recv (S, recv_data, 1024,0 );
If (RT = socket_error)
{
Printf ("receive nothing/N ");
Return-1;
}
Recv_data [RT] = '/0 ';
If (* recv_data = '5 ')
{
Printf ("the order is not support SMTP host/N ");
Return-1;
}
Printf ("% s/n", recv_data );
Return 1;
}
Int createsocket ()
{
Long T = 5000;
S = socket (af_inet, sock_stream, 0 );
If (S = socket_error)
{
Printf ("socket init error/N ");
Shutdown (S, sd_both );
Close (s );
Return-1;
}
Return 1;
}
Int connecthost (const char * hostname)
{
// Printf ("socket ID: % d/N", S );
If (hostname = NULL)
Return-1;
Memset (& remote, 0, sizeof (struct sockaddr ));
Remote. sin_family = af_inet;
Remote. sin_port = htons (port );
Remote. sin_addr.s_addr = inet_addr (hostname );
RT = connect (S, (struct sockaddr *) & remote, sizeof (struct sockaddr ));
If (RT = socket_error)
{
Printf ("Connect error/N ");
Shutdown (S, sd_both );
Close (s );
Return-1;
}
// Printf ("Connect the host OK: % d/N", Port );
If (! Getresponse ())
Return-1;
Return 1;
}
Int login (char * username, char * password)
{
Char ch [100];
If (username = NULL | Password = NULL)
Return-1;
Usersrc = username;
Passsrc = password;
Base64_code (unsigned char *) usersrc, (unsigned char *) userdes );
Base64_code (unsigned char *) passsrc, (unsigned char *) passdes );
Send_data = "ehlo localhost/R/N ";
RT = Send (S, send_data, strlen (send_data), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
If (! Getresponse ())
Return-1;
Send_data = "auth login/R/N ";
RT = Send (S, send_data, strlen (send_data), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
If (! Getresponse ())
Return-1;
Sprintf (CH, "% S/R/N", userdes );
RT = Send (S, (char *) CH, strlen (CH), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
If (! Getresponse ())
Return-1;
Sprintf (CH, "% S/R/N", passdes );
RT = Send (S, (char *) CH, strlen (CH), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
If (! Getresponse ())
Return-1;
Return 1;
}
Int Sendmail (const char * From, const char * To, const char * Date, const char * subject, const char * Data)
{
If (from = NULL | to = NULL | date = NULL | subject = NULL)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
Sprintf (from, "mail from: <% S>/R/N", from );
RT = Send (s, from, strlen (from), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
If (! Getresponse ())
Return-1;
Sprintf (to, "rcpt to: <% S>/R/N", );
RT = Send (s, to, strlen (to), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
If (! Getresponse ())
Return-1;
Send_data = "Data/R/N ";
RT = Send (S, send_data, strlen (send_data), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
If (! Getresponse ())
Return-1;
Sprintf (from, "From: % S/R/N", from );
RT = Send (s, from, strlen (from), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
Sprintf (to, "To: % S/R/N", );
RT = Send (s, to, strlen (to), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
Sprintf (date, "date: % S/R/N", date );
RT = Send (S, date, strlen (date), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
Sprintf (subject, "Subject: % S/R/N", subject );
RT = Send (S, subject, strlen (subject), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
Send_data = "/R/N ";
RT = Send (S, send_data, strlen (send_data), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
RT = Send (S, (char *) data, strlen (data), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
Send_data = "/R/N ";
RT = Send (S, send_data, strlen (send_data), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
Return 1;
}
Int end ()
{
Send_data = "/R/N ";
RT = Send (S, send_data, strlen (send_data), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
Send_data = "/R/n./R/N ";
RT = Send (S, send_data, strlen (send_data), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
If (! Getresponse ())
Return-1;
Send_data = "Quit/R/N ";
RT = Send (S, send_data, strlen (send_data), 0 );
If (RT = socket_error)
{
Shutdown (S, sd_both );
Close (s );
Return-1;
}
If (! Getresponse ())
Return-1;
Return 1;
}
Int main (INT argc, char * argv [])
{
Char * Host = "202.108.252.140"; // smtp.tom.com
Char * username = "****";
Char * Password = "****";
Char * m_from = "****@****";
Char * m_to = "****@****";
Char * m_date = "2006-4-7,22: 27 ";
Char * m_subject = "the IP and MAC address for ddns ";
Char * m_data = (char *) malloc (100 );
Char * IP = (char *) malloc (20 );
If (argc <1)
{
Printf ("agrv error/N ");
Free (m_data );
Free (IP );
}
If (getlocaladdress (IP) =-1)
{
Printf ("Get lcoal IP fail/N ");
Free (IP );
Return-1;
}
Char * vmac = (char *) malloc (20 );
If (getlocalmac (vmac) =-1)
{
Printf ("Get local Mac fail/N ");
Free (IP );
Free (vmac );
Return-1;
}
Sprintf (m_data, "the IP Address: % S/nthe MAC address: % s", IP, vmac );
// Printf ("% s/n", m_data );
From = (char *) malloc (40); // new char [40];
To = (char *) malloc (40); // new char [40];
Date = (char *) malloc (40); // new char [40];
Subject = (char *) malloc (40); // new char [40];
Filename = (char *) malloc (100 );
Recv_data = (char *) malloc (512 );
Userdes = (char *) malloc (40 );
Passdes = (char *) malloc (40 );
Port = 25;
S = invalid_socket;
If (! Createsocket ())
{
Printf ("socket create error/N ");
Return-1;
}
// Printf ("create the scoket/N ");
If (! Connecthost (host ))
{
Printf ("can not connect the host/N ");
Return-1;
}
// Printf ("Connect the SMTP host/N ");
If (! Login (username, password ))
{
Printf ("Login error/N ");
Return-1;
}
// Printf ("login/N ");
If (! Sendmail (m_from, m_to, m_date, m_subject, m_data ))
{
Printf ("send mail error/N ");
Return-1;
}
// Printf ("send mail/N ");
If (! End ())
{
Printf ("End error/N ");
Return-1;
}
// Printf ("send over/N ");
Destory ();
Return 0;
}