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

📄 mail.c

📁 Linux系统备份源代码 可基于用户自定义策略实现系统、应用数据备份
💻 C
字号:
/***************************************************************************    filename             : mail.c    begin                : Sun Nov 25 2001    copyright            : (C) 2001 by Henrik Witt-Hansen    email                : bean@daisy.net ***************************************************************************//*************************************************************************** *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************//*base configuration*/#ifdef HAVE_CONFIG_H#include <config.h>#endif/*standard includes*/#include <stdio.h>#include <pthread.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>/*local headers*/#include "sitback.h"/*special includes*/#include <sys/errno.h>#include <time.h>#include <sys/ioctl.h>#include <signal.h>#include <sys/wait.h>#include <sys/types.h>#include <sys/socket.h>#include <sys/ipc.h>#include <sys/sem.h>#include <sys/time.h>#include <netinet/in.h>#include <sys/wait.h>#include <netdb.h>#include <arpa/inet.h>/*local prototypes*/int __socket_command(int clientsocket,char *send,char *expect);/*local data*/extern int errno;/********************************************************************  int SendMail()  Send a mail with the content of some file  arguments:    file;     Name of file with message    subject;  The subject line  return:    0 on success    -1 on error********************************************************************/int SendMail(char *file,char *subject){  int clientsocket;  struct sockaddr_in dest_addr;  struct hostent *h;  char hostname[1024];  char hosts_entry[1024];  char domainname[1024];  char msg[1024];  FILE *fd;  char buffer[4096];  char *p;  int state=0;  int lookup_retry=0;  struct hostent *myhost;  time_t now;  char date[256];  struct tm *now_tm;  unsigned char CR = 0;  if(conf__smtp_host[0]!='\0')  {    /* get our local hostname */    if(gethostname(hostname,1024))    {      debug("Unable to get our local hostname\n");      log("Unable to get local hostname\n");      return -1;    }    debug("Hostname '%s'\n",hostname);    /* Try to locate a line in '/etc/hosts' with this hostname */    do    {      myhost = gethostent();      if( snprintf(hosts_entry,1024,"%s",myhost->h_name)<=0 )      {        debug("Unable to get full hostname with gethostent()\n");        log("Unable to get the full host- and domainname. Check '/etc/hosts'\n");        return -1;      }      debug("gethostent: '%s'\n",hosts_entry);    }    while( memcmp(hosts_entry,hostname,strlen(hostname)) );    debug("Got the right line from /etc/hosts\n");    strcpy(hostname,hosts_entry);    /* Make sure we have a sane hostname */    if(strchr(hostname,'.')==NULL)    {      debug("Hostname not complete (missing domain).\n");      if(getdomainname(domainname,1024-strlen(hostname)-1))      {        debug("Unable to get our local domainname\n");        log("Unable to get local domainname\n");        return -1;      }      /* Check that the domainname is ok */      if(!strcmp(domainname,"(none)"))      {        UI__Warning("  Invalid hostname and/or domainname.\n  'hostname' does not return a full host+domain name,\n  and trying to obtain your domainname with\n  'domainname' failed\n");        log("Invalid host and/or domainname. Check network settings\n");        Report("Invalid host and/or domainname. Check network settings\n");        return -1;      }      /* Combine host and domainname */      strcat(hostname,".");      strcat(hostname,domainname);      debug("Hostname seems to be '%s'\n",hostname);    }    debug("Full hostname is '%s'\n",hostname);    /* Resolv smtp hostname */    RETRY_TRANSFER:    if((h=gethostbyname(conf__smtp_host))==NULL)    {      debug("Host lookup failure for '%s'\n",conf__smtp_host);      if(lookup_retry<3)      {        debug("Retrying host lookup in case we have a slow dialup connection\n");        lookup_retry++;        goto RETRY_TRANSFER;      }      log("Host lookup failure for '%s'",conf__smtp_host);      return -1;    }    debug("smtp host ip: %s\n",inet_ntoa(*((struct in_addr *)h->h_addr)));    /* get a brand new socket */    if((clientsocket = socket(AF_INET, SOCK_STREAM, 0))==-1)    {      debug("Unable to create tcp/ip socket\n");      log("Unable to create tcp/ip socket\n");      return -1;    }    debug("Got tcp/ip socket\n");    /* Prepare to connect */    dest_addr.sin_family = AF_INET;    dest_addr.sin_port = htons(25);    dest_addr.sin_addr.s_addr = inet_addr(inet_ntoa(*((struct in_addr *)h->h_addr)));    bzero(&(dest_addr.sin_zero), 8);    /* connect */    if(connect(clientsocket, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr))==-1)    {      debug("Unable to connect\n");      close(clientsocket);      return -1;    }    debug("Connected\n");    /* First, the smtp server must send us a HELO with code 220 */    debug("Receiving initial HELO\n");    if(__socket_command(clientsocket,NULL,"220"))    {      debug("Unexpected answer from the server\n");      close(clientsocket);      return -1;    }    /* now send a HELO with our hostname, expect 250 in return */    sprintf(msg,"HELO %s\r\n",hostname);    debug("Sending HELO: %s",msg);    if(__socket_command(clientsocket,msg,"250"))    {      debug("Unexpected answer from the server\n");      log("Unexpected answer from server (HELO %s)",msg);      close(clientsocket);      return -1;    }    /* username/password ?? */    if(conf__smtp_user[0]!='\0' && conf__smtp_pass[0]!='\0')    {      /* Request authentication */      sprintf(msg,"AUTH LOGIN\r\n");      debug("Request authentication: %s",msg);      if(__socket_command(clientsocket,msg,"334"))      {        debug("Unexpected answer from the server\n");        log("Server can not do smtp authentication");        goto MAIL_TRANSFER;      }      /* Send username */      sprintf(msg,"%s\r\n",conf__smtp_user);      debug("Sending username: %s",msg);      if(__socket_command(clientsocket,msg,"334"))      {        debug("Unexpected answer from the server\n");        log("User unknown");        close(clientsocket);        return -1;      }      /* Send password */      sprintf(msg,"%s\r\n",conf__smtp_pass);      debug("Sending password: %s",msg);      if(__socket_command(clientsocket,msg,"235"))      {        debug("Unexpected answer from the server\n");        log("Incorrect password");        close(clientsocket);        return -1;      }    }    /* Prepare mail transfer */    MAIL_TRANSFER:    sprintf(msg,"MAIL FROM:<sitback@%s>\r\n",strchr(hostname,'.')+1);    debug("Prepare mail transfer: %s",msg);    if(__socket_command(clientsocket,msg,"250"))    {      debug("Unexpected answer from the server\n");      log("Sender address not accepted by mailserver");      close(clientsocket);      return -1;    }    /* Recipient */    sprintf(msg,"RCPT TO:<%s>\r\n",conf__report_mail);    debug("Recipient: %s",msg);    if(__socket_command(clientsocket,msg,"250"))    {      debug("Unexpected answer from the server\n");      log("Recipient not accepted by mailserver (%s)",msg);      close(clientsocket);      return -1;    }    /* Ready to start */    sprintf(msg,"DATA\r\n");    debug("Starting mail transfer: %s",msg);    if(__socket_command(clientsocket,msg,"354"))    {      debug("Unexpected answer from the server\n");      close(clientsocket);      return -1;    }    /* From field in the mail */    sprintf(msg,"From: sitback@%s\r\n",strchr(hostname,'.')+1);    debug("From field: %s",msg);    if(__socket_command(clientsocket,msg,NULL))    {      debug("Error while talking to the mailserver\n");      close(clientsocket);      return -1;    }    /* To field in the mail */    sprintf(msg,"To: %s\r\n",conf__report_mail);    debug("To field: %s",msg);    if(__socket_command(clientsocket,msg,NULL))    {      debug("Error while talking to the mailserver\n");      close(clientsocket);      return -1;    }    /* Subject field in the mail */    sprintf(msg,"Subject: %s - %s\r\n",subject,hostname);    debug("Subject field: %s",msg);    if(__socket_command(clientsocket,msg,NULL))    {      debug("Error while talking to the mailserver\n");      close(clientsocket);      return -1;    }    /* Date field in the mail */    now = time(NULL);    now_tm = localtime(&now);    strftime(date,256,"%a,  %d  %b  %Y  %H:%M:%S  %z",now_tm);    sprintf(msg,"Date: %s\r\n",date);    debug("Date field: %s",msg);    if(__socket_command(clientsocket,msg,NULL))    {      debug("Error while talking to the mailserver\n");      close(clientsocket);      return -1;    }    /* Send the report */    if((fd=fopen(file,"r"))==NULL)    {      debug("Unable to open the specified file '%s'\n",file);      if(__socket_command(clientsocket,"(Internal error: Unable to open the report)\r\n",NULL))      {        debug("Error while talking to the mailserver\n");        close(clientsocket);        return -1;      }    }    else    {      debug("Transmitting report file '%s'\n",file);      for(;;)      {        /* Get a chunk */        memset(buffer,'\0',1025);        fread(buffer,1024,1,fd);        /* Check for standalone linefeeds */        p=buffer;        while( *p!='\0' )        {          if( *p=='\r' )          {            CR = 1;          }          else if( *p=='\n' && CR==0 )          {            memmove(p+1,p,strlen(p)+1);            *p = '\r';            p++;          }          else            CR = 0;          p++;        }        /* Send the buffer */        if(__socket_command(clientsocket,buffer,NULL))        {          debug("Error while talking to the mailserver\n");          close(clientsocket);          fclose(fd);          return -1;        }        /* Anymore data ?? */        if(feof(fd))          break;      }      fclose(fd);    }    /* Ending mail transfer */    sprintf(msg,"\r\n.\r\n");    debug("Ending mail transfer\n");    if(__socket_command(clientsocket,msg,"250"))    {      debug("Unexpected answer from the server\n");      close(clientsocket);      return -1;    }    /* Close connection */    sprintf(msg,"QUIT\r\n");    debug("Sending QUIT\n");    if(__socket_command(clientsocket,msg,"221"))    {      debug("Unexpected answer from the server\n");      close(clientsocket);      return -1;    }    /* close the socket */    debug("Closing socket\n");    close(clientsocket);  }  /* done */  return 0;}/********************************************************************  int __socket_command()  Send on a socket, thereafter receive an answer  and compare agains an 'expected' string  arguments:    clientsocket:  The socket to use    send;          String to send, NULL if nothing is to be send    expect;        Receive an answer and compare to this string  returns:    0 on success    1 if compare fails    -1 on error********************************************************************/int __socket_command(int clientsocket,char *send,char *expect){  int rc;  unsigned len;  char recv[1025];  int result=0;  fd_set rfds;  struct timeval tv;  /* paranoid check */  if(expect!=NULL && strlen(expect)>1024)  {    debug("Internal error: Unable to compare more than 1024 characters\n");    return -1;  }  /* Anything to send ?? */  if(send!=NULL)  {    len=0;    while(len<strlen(send))    {      if((rc=write(clientsocket,send,strlen(send)))==-1)      {        debug("Error in write(), '%s'\n",strerror(errno));        return -1;      }      len+=rc;      debug("rc=%d  len=%u\n",rc,len);    }  }  /* should we try to receive an answer ?? */  if(expect!=NULL)  {    /* wait until some data is available, or timeout */    debug("Waiting until there is data on the socket\n");    FD_ZERO(&rfds);    FD_SET(clientsocket,&rfds);    tv.tv_sec=30;    tv.tv_usec=0;    if(select(clientsocket+1,&rfds,NULL,NULL,&tv)<1)    {      debug("Timeout waiting for answer on socket\n");      return -1;    }    /* Read some data */    debug("Receiving answer\n");    if((rc=read(clientsocket,recv,1024))==-1)    {      debug("Error in read(), '%s'\n",strerror(errno));      return -1;    }    recv[rc]='\0';    /* compare */    debug("expect: %s\n",expect);    debug("recv: %s",recv);    if(rc<strlen(expect))      result=1;    else if(memcmp(recv,expect,strlen(expect)))      result=1;    debug("result=%d\n",result);    /* Keep receiving if there is more data on the socket */    if(rc==1024)    {      debug("Trying to clean the socket\n");      for(;;)      {        /* wait until some data is available, or timeout */        debug("Waiting until there is data on the socket\n");        FD_ZERO(&rfds);        FD_SET(clientsocket,&rfds);        tv.tv_sec=3;        tv.tv_usec=0;        if(select(clientsocket+1,&rfds,NULL,NULL,&tv)<1)        {          debug("No more data on the socket (timeout)\n");          break;        }        /* Read some data */        debug("Receiving answer\n");        if((rc=read(clientsocket,recv,1024))==-1)        {          debug("Error in read(), '%s'\n",strerror(errno));          return -1;        }        debug("rc=%d\n",rc);        recv[rc]='\0';        debug("Received: '%s'\n",recv);        if(rc!=1024)        {          debug("No more data\n");          break;        }      }    }  }  /* done */  return result;}

⌨️ 快捷键说明

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