/***************************************
  $Revision: 1.8 $

  AK (Acknowledgement) module

  Status: NOT REVIEWED, NOT TESTED

  Author(s):       Engin Gunduz

  ******************/ /******************
  Modification History:
        engin (10/06/2000) Created.
  ******************/ /******************
  Copyright (c) 2000                              RIPE NCC
 
  All Rights Reserved
  
  Permission to use, copy, modify, and distribute this software and its
  documentation for any purpose and without fee is hereby granted,
  provided that the above copyright notice appear in all copies and that
  both that copyright notice and this permission notice appear in
  supporting documentation, and that the name of the author not be
  used in advertising or publicity pertaining to distribution of the
  software without specific, written prior permission.
  
  THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 ***************************************/



#include "ack.h"
extern int supress_ack_notif;
extern char * humailbox;
extern char * defmail;


/*

  AK_add_to_ack: writes a message to the acknowledgement file.

*/

void AK_add_to_ack(char * filename, char * fmt, ...){

  va_list ap;  /* points to each unnamed arg in turn */
  char *p, *sval;
  int ival;
  double dval;
  FILE * ack_file;
  
  if(( ack_file = fopen(filename, "a")) == NULL){
    fprintf(stderr, "Can't open ack file, %s", filename);
  }
    
  va_start(ap, fmt);
  
  for(p = fmt; *p; p++){
    if (*p != '%') {
      fprintf(ack_file, "%c", *p);
      continue;
    }
    switch(*++p) {
    case 'd':
      ival = va_arg(ap, int);
      fprintf(ack_file, "%d", ival);
      break;
    case 'f':
      dval = va_arg(ap, double);  
      fprintf(ack_file, "%f", dval);
      break;
    case 'X':
      ival = va_arg(ap, int);
      fprintf(ack_file, "%X", ival);
      break;
    case 'x':
      ival = va_arg(ap, int);
      fprintf(ack_file, "%x", ival);
      break;
    case 's':
      //for(sval = va_arg(ap, char *); *sval; sval++)
      //  putchar(*sval);
      sval = va_arg(ap, char *);
      fprintf(ack_file, "%s", sval);
      break;
    default:
      putchar(*p);
      break;
    }
  }

  va_end(ap); /* clean up */
  fclose(ack_file);
}

/*  */
void AK_add_to_ack_string(const char * file_name, const string msg){

   ofstream ack_file(file_name, ios::app);

   if(!ack_file){
     cerr << "Couldn't open ack file" << endl;
     return;
   }
   ack_file << msg;
   ack_file.close();
}




/*

  AK_ack_file_name_generate: Generates a unique name for temporary acknowledgement
     files, and also creates it. 

      tmpdir: temporary directory (without a trailing '/')
      prefix: prefix for the temp file
      
      returns: the generated name. 
     

*/

char * AK_ack_file_name_generate( const char * tmpdir, const char * prefix){

   FILE * ack_file;
   char * name;
      
   /* allocate space for name. 32 should be enough for PID */
   name = (char*)malloc(strlen(tmpdir) + strlen(prefix) + 32); 
   
   sprintf(name, "%s/%s.%i", tmpdir, prefix, getpid());

   /* create the file */
   if(( ack_file = fopen(name, "w")) == NULL){
     fprintf(stderr, "Can't open ack file, %s", name);
   }

   /* close it */
   fclose(ack_file);
    
   return name;

}


/* 

AK_send_ack: sends the ack message contained in the temp file.
 
   
*/

void AK_send_ack( const char * filename, const char * to_address, const char * mailercommand){

    char * mail_command_line = NULL;
    char * supress_file = NULL;
    FILE * ack_file, * supr_file_hdl;
    char buf[1024];

    /* if we are not supressing acks and notifs, send the ack */
    if(!supress_ack_notif){
      if(to_address != NULL){
        mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(to_address) 
            + strlen(filename) + 128);
        sprintf(mail_command_line, "%s %s < %s", mailercommand, to_address, filename);
        system(mail_command_line);
      }
    /* if we are supressing acks and notifs, send ack to DEFMAIL  */
    }else{
      supress_file = (char *)malloc(strlen(filename) + strlen(".supress") + 2); 
      sprintf(supress_file, "%s.supress", filename);
      if(( supr_file_hdl = fopen(supress_file, "w")) == NULL){
        fprintf(stderr, "Can't open supress ack file, %s", supress_file);
      }else{
        fprintf(supr_file_hdl, "From: %s\nTo: %s\nSubject: Supressed ack mail\n\n",
            humailbox, defmail);
        if(( ack_file = fopen(filename, "r")) == NULL){
          fprintf(stderr, "Can't open ack file for reading, %s", filename);
        }else{
          while(fgets(buf, 1024, ack_file) != NULL){
            fprintf(supr_file_hdl, buf);
          }
          fclose(ack_file);
        }
      }
      fclose(supr_file_hdl);
      mail_command_line = (char *)malloc(strlen(mailercommand) + strlen(defmail) 
            + strlen(supress_file) + 128);
      sprintf(mail_command_line, "%s %s < %s", mailercommand, defmail, supress_file);
      system(mail_command_line);
      unlink(supress_file);
      free(supress_file);
    }


}


/*

  AK_delete_ack: deletes the temporary acknowledgement file.

*/

void AK_delete_ack( const char * filename ){

   unlink(filename);   

}

/*

AK_log_ack: logs the acknowledgements in the log_file.

*/

void AK_log_ack(const char * filename, const char * logfilename){

  FILE * ack_file, * log_file;
  char * buf;
  time_t cur_time;
  char * time_str;

  buf = (char *)malloc(1024);
  if(( ack_file = fopen(filename, "r")) == NULL){
    fprintf(stderr, "Can't open ack file, %s\n", filename);
    return;
  }

  if(( log_file = fopen(logfilename, "a")) == NULL){
    fprintf(stderr, "Can't open log file, %s\n", logfilename);
    return;
  }

  /* get time */
  cur_time = time(NULL);
  time_str = strdup(ctime(&cur_time));
  /* cut the '\n' at the end */
  time_str[strlen(time_str) - 1] = '\0';

  fprintf(log_file, ">>> time: %s ACK <<<\n\n", time_str);


  while((buf=fgets(buf, 1023, ack_file)) > 0){
    fprintf(log_file, "%s", buf);
  }

  free(time_str);
  fclose(ack_file);
  fclose(log_file);

}








