#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/types.h>    /* FreeBSD reportedly needs this */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>


#include "../global.h"
#include "../custom.h"

#include "shared_util.h"
#include "shared_strtrm.h"
#include "shared_file_util.h"
#include "shared_lock.h"
#include "shared_cs_util.h"


void
lookup_remote_host()
{
 #define UNKNOWN_HOST "???"
 struct in_addr address;
 struct hostent *ptr;
 
 char *remote_host;
 char *remote_address;
 
 remote_host = hdf_get_value(global_cgi->hdf, "CGI.RemoteHost","");
 remote_address = hdf_get_value(global_cgi->hdf, "CGI.RemoteAddress","");
 
 if(!*remote_address)    /* then there's not much we can do */
  {
   hdf_set_value(global_cgi->hdf, "CGI.RemoteAddress", UNKNOWN_HOST); 
   hdf_set_value(global_cgi->hdf, "CGI.RemoteHost", UNKNOWN_HOST); 
   return;
  }
 
 /* ENABLE_DNS_LOOKUPS is #defined in custom.h */
 if(!ENABLE_DNS_LOOKUPS && !*remote_host)  /* just set RemoteHost = RemoteAddress */
  {
   hdf_set_value(global_cgi->hdf, "CGI.RemoteHost", remote_address);
   return;
  } 
 
 /* ENABLE_DNS_LOOKUPS is #defined in custom.h */
 if(ENABLE_DNS_LOOKUPS && !*remote_host)   // only do lookup if we already don't have a value 
  {
     if(inet_aton(remote_address, &address))    // convert dotted quad to internet address 
      {
       ptr = gethostbyaddr((char *) &address.s_addr, sizeof(address.s_addr), AF_INET); // attempt to lookup host name 
       if(ptr)
         hdf_set_value(global_cgi->hdf, "CGI.RemoteHost", ptr->h_name);
       else
         hdf_set_value(global_cgi->hdf, "CGI.RemoteHost", remote_address);  
      }   
  }  

#undef UNKNOWN_HOST
}       




void
write_last_login(const char *filename)
{
    FILE *fp;
    time_t now;
    char time_string[MAX_TIMESTRING +1];
    
    now =time(NULL);
    strftime(time_string, MAX_TIMESTRING,DOW_DATE_TIME_FORMAT, localtime(&now));

    lookup_remote_host();   /* set the RemoteAddress and RemoteHost values */

    fp = fopen(filename, "w");
    if(!fp)
      cs_critical_error(ERR_FOPEN_WRITE_FAILED, filename);
    fprintf(fp, "%s\n%s\n", time_string, hdf_get_value(global_cgi->hdf, "CGI.RemoteHost", "???"));   
    fclose(fp);
}



void
get_last_time_login(const char *file_name, char *login_time, char *login_host)
{
 #define MAX_LINE 300

    char line[MAX_LINE + 1 ];
    FILE *fp;
    int set_new_login_time = 1;


    if(file_exists(file_name))   /* shared_file_util.c */
    {
      fp = fopen(file_name, "r");
      if(!fp)
        cs_critical_error(ERR_FOPEN_READ_FAILED, file_name);
      
      if(fgets(line,MAX_LINE+1, fp))
       {
         strtrm(line);    /* shared_strtrm.c */
         strncpy(login_time, line, MAX_TIMESTRING + 1);
      
         if(fgets(line,MAX_LINE+1, fp))
          {
           strtrm(line);    /* shared_strtrm.c */
           strncpy(login_host, line, MAX_PATH + 1);
      
           set_new_login_time = 0;
      
           fclose(fp);
           write_last_login(file_name);
          }
     } 
    }

   if(set_new_login_time) 
    {
      *login_time = '\0';
      *login_host = '\0';
      write_last_login(file_name);
    }
#undef MAX_LINE
} 



   



void
write_central_log(const char *username, const char *event, const char *event_attribute, int is_admin)
{
	
  FILE *fp;
  int fd;
  time_t now;
  char user_log_path[MAX_PATH +1];
  char time_string[MAX_TIMESTRING +1];

  now = time (NULL);
  strftime(time_string, MAX_TIMESTRING, DOW_DATE_TIME_FORMAT, localtime(&now));
 
  /* set CGI.RemoteAddress and CGI.RemoteHost */
  lookup_remote_host();
  
  
  snprintf (user_log_path, MAX_PATH +1, "%s/%s", LOG_PATH, LOG_FNAME);
  fp = fopen(user_log_path, "a+");
  if(!fp)
	  cs_critical_error(ERR_FOPEN_APPEND_FAILED, user_log_path);
  fd = fileno(fp);
  get_exclusive_lock(fd, 1);   /* shared_lock.c */
  
  fprintf(fp, "%s%s\n",  is_admin? hdf_get_value(global_cgi->hdf, "log_event.admin_prefix","") : "" ,username);
  fprintf(fp, "%s %s\n", event, event_attribute);
  fprintf(fp, "%s\n", time_string);
  fprintf(fp, "%s\n",  hdf_get_value(global_cgi->hdf,"CGI.RemoteHost","???"));   /* just print whatever the environment variable is */
  fprintf(fp, "%s\n", hdf_get_value(global_cgi->hdf, "CGI.RemoteAddress","???"));
  fprintf(fp, "%s\n",  hdf_get_value(global_cgi->hdf, "HTTP.UserAgent","???"));

  release_lock(fd);  /*shared_lock.c */
  fclose(fp);
}
