/**************************************************
OpengateM - MAC address authentication system 

 Module for sending warning mail to users at the expiration date.
 This program searchs devices that are expired soon, and send out 
 warning mail to the registered mail address of their owners.

 'conf/warningmail.sample' is the sample template file of mail.
 Copy it to 'conf/warningmail' and modify to match your site.
 Leave variables '%%DEVICENAME%%' and '%%LIMITDATE%%' in the file 
 untouched. These are replaced properly by this program.
 
Copyright (C) 2011 Opengate Project Team
Written by Yoshiaki Watanabe

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.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

Email: watanaby@is.saga-u.ac.jp
**************************************************/

#include	"opengatemmng.h"

/**********************************/
/*  main routine run as cron      */
/**********************************/
int  main(int argc, char **argv)
{
  char mailAddress[BUFFMAXLN]=""; /* mail address */
  char limitDate[WORDMAXLN]="";   /* limit(expiration) date */
  char device[WORDMAXLN]="";      /* device(terminal) name */
  char deviceList[BUFFMAXLN]="";  /* device name list (concat of device) */
  char mailAddressPrev[BUFFMAXLN]=""; /* mail address of previous record */
  char limitDatePrev[WORDMAXLN]="";   /* limit date of previous record */
  int count=0;                    /* count of sending mails */
  char* progName;                 /* the name of this program in argv[0] */

  /* drop root privilege */
  seteuid(getuid());

  /* if this is executed in shell with '-v' option, show makedir */  
  if(argc>1){
    if(strcmp(argv[1],"-v")==0){
      printf("makedir: %s\n", MAKEDIR);
    }else{
      printf("This is the program used with cron\n");
      printf("To show version, run this on console with '-v' option\n");
    }
    exit(0);
  }

  /* save program load path */
  saveLoadPath(argv[0]);
  progName = getProgramName();

  /* prepare config file */
  if(OpenConfFile()==-1){
    PutMessageToClient("Check config file by running this cgi on console");
    return 0;
  }
 
  /* start log */
  errToSyslog(atoi(GetConfValue("Syslog/Enable")));
  openlog(progName, LOG_PID, atoi(GetConfValue("Syslog/Facility")));

  /* initialize config */
  InitConf();
  if(!InitMngDb()) return 0;

  /* get first mail address near expiration date */
  /* use same funciiton for first/next call (branch in the function) */ 
  if(GetNextMailAddressFromMngDb(mailAddress, limitDate, device)){

    /*** following code summarizes the information of devices having */
    /*   same mailAddress and limitDate to one mail */
    
    /* if get, save the first record */
    strncpy(mailAddressPrev, mailAddress, BUFFMAXLN);
    strncpy(limitDatePrev, limitDate, WORDMAXLN);
    strncpy(deviceList, device, WORDMAXLN);

    /* get next mail address near expiration date */
    while(GetNextMailAddressFromMngDb(mailAddress, limitDate, device)){

      /* if mailAddress or limitDate are not same as previous */
      if( strcmp(mailAddress, mailAddressPrev)!=0 
	 || strcmp(limitDate, limitDatePrev)!=0 ){

	/* send mail to the address and clear deviceList */
	if(!isNull(mailAddressPrev)){
	  if(SendMail(mailAddressPrev, limitDatePrev, deviceList)) count++;
	}
	deviceList[0]='\0';
      }

      /* save the mail Address and limit date */
      strncpy(mailAddressPrev, mailAddress, BUFFMAXLN);
      strncpy(limitDatePrev, limitDate, WORDMAXLN);

      /* add the device name to the deviceList
       if list is too long, it is terminated by ", ......" */
      if(isNull(deviceList)){
	strncpy(deviceList, device, WORDMAXLN);
      }
      else if(strstr(deviceList, ", ......")!=NULL) ;
      else if( strlen(deviceList) > BUFFMAXLN*0.8 ){
	strncat(deviceList, ", ......", BUFFMAXLN); 
      }
      else{
	strncat(deviceList, ", ", BUFFMAXLN); 
	strncat(deviceList, device, BUFFMAXLN);
      }
    }

    /* post processing of residue at the end of get loop */
    if( !isNull(mailAddressPrev) ){
      if(SendMail(mailAddressPrev, limitDatePrev, deviceList)) count++;
    }
  }

  /* finalize */
  CloseMngDb();

  /* report to syslog */
  if(debug>0)  err_msg("INFO: Sended %d mails",count); 

  return 0;
}

/**************************************************/
/* send mail                                      */
/**************************************************/
int sendMail(char* mailAddress, char* limitDate, char* device)
{
  FILE* mailer;
  FILE* fp;
  char mailCmd[BUFFMAXLN];
  char buff[BUFFMAXLN];
  char* mailCmdPath;
  struct stat st;

  /* set mail command path (/bin/rmail) */
  mailCmdPath=GetConfValue("Mail/CmdPath");
  if(isNull(mailCmdPath)){
    err_msg("ERR at %s#%d: cannot get Mail/CmdPath from conf",__FILE__,__LINE__);
    return FALSE;
  }

  /* if mail command is not exists, return */
  if(stat(mailCmdPath, &st)!=0){
    err_msg("ERR at %s#%d: mail command[%s] is not found",__FILE__,__LINE__,mailCmdPath);
    return FALSE;
  }

  /* prepare mail command as [/bin/rmail user@domain] */
  strlcpy(mailCmd, mailCmdPath, BUFFMAXLN);
  strlcat(mailCmd, " ", BUFFMAXLN);
  strlcat(mailCmd, mailAddress, BUFFMAXLN);

  /* prepare a pipe connected to the mail command */
  mailer = popen(mailCmd, "w");
  if(mailer==NULL){
    err_msg("ERR at %s#%d: cannot open pipe",__FILE__,__LINE__);
    return FALSE;
  }

  /* open the mail content file to read in */
  if((fp=fopen(GetConfValue("Mail/Content"), "r"))==NULL){
    err_msg("ERR at %s#%d: cannot find file %s",__FILE__,__LINE__, 
	    GetConfValue("Mail/Content"));
    return FALSE;
  }

  /* read mail content file, replace variables, and write to the pipe */
  while(fgets(buff,BUFFMAXLN,fp)!=NULL){
    HtmlReplace(buff, "%%MAILADDRESS%%", mailAddress);
    HtmlReplace(buff, "%%LIMITDATE%%", limitDate);
    HtmlReplace(buff, "%%DEVICENAME%%", device);
    fputs(buff, mailer);    
  }
  fclose(fp);
  pclose(mailer);
  return TRUE;
}

/***********************************************
 routines for debugging output
***********************************************/
int SendMail(char* mailAddress, char* limitDate, char* device){
    int ret;
  if(debug>1) err_msg("DEBUG:=>sendMail(%s,%s,%s)", 
		      mailAddress, limitDate, device);
  ret=sendMail(mailAddress, limitDate, device);
  if(debug>1) err_msg("DEBUG:(%d)<=sendMail( )",ret);
  return ret;
}
