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

📄 ssmtp.c

📁 ssmt邮件服务器armlinux下的邮件开发
💻 C
📖 第 1 页 / 共 3 页
字号:
///////////////////////////////////////////////////////////////////////// FILE DESCRIPTION//	This file plays as simple SMTP (ssmtp) client communication//// NOTE//	For each response we wait 5 seconds since,//	you know, wireless LAN is unstable, sometimes.////	For attached file sending, we encoded it as base 64 MIME//	format by using free sourcing encode package.////	Each time sending mail, the number of attachment is only one//	Adjust it if you need to send out more than one attachments//	at function encode	//// VERSION//	0.01 (2005/11/7)//// AUTHOR//	Jerry Huang///////////////////////////////////////////////////////////////////////#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/param.h>#include <sys/time.h>#include <netinet/in.h>#include <netdb.h>#include <ctype.h>#include <arpa/inet.h>#include <errno.h>#include <fcntl.h>#include "ssmtp.h"///////////////////////////////////////////////////////////////////////// Functions///////////////////////////////////////////////////////////////////////extern char *md5digest(FILE *infile, long int *len);extern int to64(FILE *infile, FILE *outfile, long int limit);int ssmtp_usage(void);int ssmtp_init(SMTP_Client_Info *smtpinfo, int argc, char *argv[]);int ssmtp_connect(SMTP_Client_Info *smtpinfo);int ssmtp_read(SMTP_Client_Info *smtpinfo, char *buf);int ssmtp_send(SMTP_Client_Info *smtpinfo, char *buf);int ssmtp_ready(SMTP_Client_Info *smtpinfo, char *buf);int ssmtp_helo(SMTP_Client_Info *smtpinfo, char *status_code);int ssmtp_ehlo(SMTP_Client_Info *smtpinfo, char *status_code);int ssmtp_mail(SMTP_Client_Info *smtpinfo, char *status_code);int ssmtp_rcpt(SMTP_Client_Info *smtpinfo, char *status_code);int ssmtp_data(SMTP_Client_Info *smtpinfo, char *status_code);int ssmtp_content(SMTP_Client_Info *smtpinfo, char *status_code);int ssmtp_auth(SMTP_Client_Info *smtpinfo);int ssmtp_quit(SMTP_Client_Info *smtpinfo);void ssmtp_failed(int error_code);///////////////////////////////////////////////////////////////////////// Global Variables///////////////////////////////////////////////////////////////////////static char mail_date[100];static char *mail_subject="Alarm from IP-camera";static char *tmp_host="";static char *tmp_fromaddr="IP-camera";static char *tmp_toaddr="";static char *tmp_domain="";static char *tmp_auth_user="";static char *tmp_auth_pass="";static char *tmp_port="";static char *tmp_auth="";static char attachment[80];static char *mail_body="Motion detected as attachment!";static char mimetmpfile[80];// Description of the various file formats and their magic numbersstruct magic{    char *name;	// Name of the file format    char *num;	// The magic number    int len;	// Length of same (0 means strlen(magicnum))};// The magic numbers of the file formats we know aboutstatic struct magic magic[] ={    { "image/gif", "GIF", 0 },    { "image/jpeg", "\377\330\377", 0 },    { "video/mpeg", "\0\0\001\263", 4 },    { "application/postscript", "%!", 0 },};static int num_magic = (sizeof(magic)/sizeof(magic[0]));static int max_magiclen = 0; // The longest magic numberstatic char *default_type = "application/octet-stream";static const char base64digits[] =   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";static char ssmtp_stored_message[MAXDATASIZE];///////////////////////////////////////////////////////////////////////// Function sendall////	be sure that system call send() sent out all data/////////////////////////////////////////////////////////////////////////int sendall(int s, char *buf, int len){	int total = 0;			// how many bytes we sent	int bytesleft = len;	// how many we have left to send	int n;		while(total < len)	{		n = send(s, buf+total, bytesleft, 0);		if (n < 0)		{			perror("send");			return -1;		}				total += n;		bytesleft -= n;	}	len = total;	// number of bytes actually sent	return 0;		// return -1 on failure, 0 on success}///////////////////////////////////////////////////////////////////////// Function magic_look////	Determins the format of the file "inputf".  The name//	of the file format (or NULL on error) is returned./////////////////////////////////////////////////////////////////////////char *magic_look(FILE *infile){    int i, j;    char buf[80];    int numread = 0;    if (max_magiclen == 0)    {		for (i=0; i<num_magic; i++)		{		    if (magic[i].len == 0) magic[i].len = strlen(magic[i].num);		    if (magic[i].len > max_magiclen) max_magiclen = magic[i].len;		}    }    numread = fread(buf, 1, max_magiclen, infile);    rewind(infile);    for (i=0; i<num_magic; i++)    {		if (numread >= magic[i].len)		{		    for (j=0; j<magic[i].len; j++)		    {				if (buf[j] != magic[i].num[j]) break;		    }		    if (j == magic[i].len) return magic[i].name;		}    }    return default_type;}///////////////////////////////////////////////////////////////////////// Function os_genid////	Generate a message-id/////////////////////////////////////////////////////////////////////////char *os_genid(void){    static int pid = 0;    static time_t curtime;    static char hostname[MAXHOSTNAMELEN+1];    char *result;    struct hostent *hp;        if (pid == 0)    {		pid = getpid();		time(&curtime);		gethostname(hostname, sizeof(hostname));			// If we don't have a FQDN, try canonicalizing with gethostbyname		if (!strchr(hostname, '.'))		{		    hp = gethostbyname(hostname);		    if (hp)		    {				strcpy(hostname, hp->h_name);		    }		}    }    result = malloc(25+strlen(hostname));    sprintf(result, "%d.%d@%s", pid, curtime++, hostname);    return result;}///////////////////////////////////////////////////////////////////////// Function os_createnewfile////	create file for encoded MIME output/////////////////////////////////////////////////////////////////////////FILE *os_createnewfile(char *fname){    int fd;    FILE *ret;     #ifdef O_EXCL    fd=open(fname, O_RDWR|O_CREAT|O_EXCL, 0644);#else    fd=open(fname, O_RDWR|O_CREAT|O_TRUNC, 0644);#endif    if (fd == -1)        return NULL;         ret=fdopen(fd, "w");    return ret;}///////////////////////////////////////////////////////////////////////// Function os_perror////	print out create file error/////////////////////////////////////////////////////////////////////////void os_perror(char *file){    perror(file);}///////////////////////////////////////////////////////////////////////// Function encode////	Encode a file into one or more MIME messages, each//	no larger than 'maxsize'. A 'maxsize' of zero means no size limit.//	If 'applefile' is non-null, it is the first part of a//	multipart/appledouble pair.//// PARAMETERS://	infile			= file description for the attached file//	applefile		= not used//	fname			= attached file name//	desc			= MAILMSG, mail message//	subject			= MAILSUBJECT, mail subject//	headers			= 0, not used//	maxsize			= 0, not used//	typeoverride	= 0, not used//	outfname		= file to be create for whole MIME encoded message///////////////////////////////////////////////////////////////////////int encode(FILE *infile, FILE *applefile, char *fname, char *desc, char *subject,           char *headers, long int maxsize, char *typeoverride, char *outfname){    char *type;    FILE *outfile;    char *cleanfname, *p;    char *digest, *appledigest;    long filesize, l, written;    int thispart, numparts = 1;    int wrotefiletype = 0;    char *multipartid, *msgid, *referenceid[NUMREFERENCES];    char buf[1024];    int i;    // Clean up fname for printing    cleanfname = fname;#ifdef __riscos    // This filename-cleaning knowledge will probably    // be moved to the os layer in a future version.    //    if (p = strrchr(cleanfname, '.')) cleanfname = p+1;#else    if (p = strrchr(cleanfname, '/')) cleanfname = p+1;    if (p = strrchr(cleanfname, '\\')) cleanfname = p+1;#endif    if (p = strrchr(cleanfname, ':')) cleanfname = p+1;    // Find file type    type = magic_look(infile);    if (typeoverride)    {		type = typeoverride;    }    else    {		type = magic_look(infile);    }    // Compute MD5 digests    digest = md5digest(infile, &filesize);    if (applefile)    {		appledigest = md5digest(applefile, &l);		filesize += l;    }#if 0    // See if we have to do multipart    if (maxsize)    {		filesize = (filesize / 54) * 73; // Allow for base64 expansion		// Add in size of desc file		if (descfile)		{		    free(md5digest(descfile, &l)); 	// XXX		    filesize += l;		}		numparts = (filesize-1000)/maxsize + 1;		if(numparts < 1) numparts = 1;    }#endif    multipartid = os_genid(); // generate output ID (message ID)    for (i=0; i<NUMREFERENCES; i++)    {		referenceid[i] = 0;    }    // main encode loop    for (thispart=1; thispart <= numparts; thispart++)    {	written = 0;	/* Open output file */	if (numparts == 1)	{	    outfile = os_createnewfile(outfname);	}	else	{#ifdef __riscos	    /* Arrgh, riscos uses '.' as directory separator */	    sprintf(buf, "%s/%02d", outfname, thispart);#else	    sprintf(buf, "%s.%02d", outfname, thispart);#endif	    outfile = os_createnewfile(buf);	}	if (!outfile) // file open failed	{	    os_perror(buf);            return 1;    }		msgid = os_genid();	fprintf(outfile, "Message-ID: <%s>\r\n", msgid);	fprintf(outfile, "Mime-Version: 1.0\r\n");	if (headers) fputs(headers, outfile);	if (numparts > 1)	{	    fprintf(outfile, "Subject: %s (%02d/%02d)\r\n", subject, thispart, numparts);	    if (thispart == 1)	   	{			referenceid[0] = msgid;	    }	    else	    {			// Put out References: header pointing to previous parts			fprintf(outfile, "References: <%s>\r\n", referenceid[0]);			for(i=1; i<NUMREFERENCES; i++)			{			    if (referenceid[i])			    	fprintf(outfile, "\t <%s>\r\n", referenceid[i]);			}						for(i=2; i<NUMREFERENCES; i++)			{			    referenceid[i-1] = referenceid[i];			}						referenceid[NUMREFERENCES-1] = msgid;	    }	    	    fprintf(outfile, "Content-Type: message/partial; number=%d; total=%d;\r\n", thispart, numparts);	    fprintf(outfile, "\t id=\"%s\"\r\n", multipartid);	    fprintf(outfile, "\r\n");	}	if (thispart == 1)	{        // if multi-part, new Message-ID has to be appended	    if (numparts > 1)	    {			fprintf(outfile, "Message-ID: <%s>\r\n", multipartid);			fprintf(outfile, "MIME-Version: 1.0\r\n");	    }			    fprintf(outfile, "Subject: %s\r\n", subject);	    fprintf(outfile, "Content-Type: multipart/mixed; boundary=\"-\"\r\n");	    fprintf(outfile, "\r\nThis is a MIME encoded message.  Decode it with \"munpack\"\r\n");	    fprintf(outfile, "or any other MIME reading software.  Mpack/munpack is available\r\n");	    fprintf(outfile, "via anonymous FTP in ftp.andrew.cmu.edu:pub/mpack/\r\n");	    written = 300;        // SMTP body message here!!        // Original from a file, now modified from a string	    if (desc)	    {			fprintf(outfile, "---\r\n\r\n");			#if 0			while(gets(buf, sizeof(buf), desc))			{			    // Strip multiple leading dashes as they may become MIME boundaries			    p = buf;			    			    if (*p == '-')			    {					while (p[1] == '-') p++;			    }				    fputs(p, outfile);			    written += strlen(p);			}			#endif			p = desc;			if(*p=='-')			{				while(p[1] == '-')					p++;			}						fputs(p, outfile);			fprintf(outfile, "\r\n\r\n");	    }    	    fprintf(outfile, "---\r\n"); // SMTP body message boundary        // jry, we are not applefile	    if (applefile)	    {			fprintf(outfile, "Content-Type: multipart/appledouble; boundary=\"=\"; name=\"%s\"\r\n", cleanfname);			fprintf(outfile, "Content-Disposition: inline; filename=\"%s\"\r\n", cleanfname);			fprintf(outfile, "\r\n\r\n--=\r\n");			fprintf(outfile, "Content-Type: application/applefile\r\n");			fprintf(outfile, "Content-Transfer-Encoding: base64\r\n");			fprintf(outfile, "Content-MD5: %s\r\n\r\n", appledigest);			free(appledigest);			written += 100;	    }	}    // jry, we are not applefile	if(applefile && !feof(applefile))	{	    if (written == maxsize)	    	written--; // avoid a nasty fencepost error	    	    written += to64(applefile, outfile, (thispart == numparts) ? 0 : (maxsize-written));	    if (!feof(applefile))

⌨️ 快捷键说明

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