#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
#include<sys/socket.h>
#include<sys/wait.h>
#include<string.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<pthread.h>

#include"zither.h"
#include<almemsys/almemsys.h>
#include"jpreturn.h"


// V6 対応

extern global_data_t gd;


/*--------------- NEG_LOGIC ------------------- */
int neg_logi(private_data_t * pd)
{
int stat, sostat;
int count;
char * tmp;

#ifndef BIG_WOOD
char * swapsubject;
char * swapdata;
#endif

stat = 0;
sostat = 0;
count = 0;

if(((int)neg(pd->rec.user, gd.fp.neg_conf, (unsigned char *)gd.ms.inip_addr[pd->rec.fdno]))==1){
   pd->file.lock_filename = chack_lockfile(pd->rec.user, pd->rec.info, pd->file.lock_filename, gd.fp.lock_path, &stat);

   pd->file.clock_filename = filename_create(pd->file.clock_filename, gd.fp.clock_path, "_lock", pd->rec.user);
   lock_remove(pd->file.clock_filename);



   #ifdef DEBUG
   printf("DEBUG: neg_logi(): my lock file name & path. %s\n", pd->file.lock_filename);
   printf("DEBUG: neg_logi(): my clock file name & path. %s\n", pd->file.clock_filename);
   #endif

   if(stat == 1){

      pd->rec.def_user = safe_memcpy(pd->rec.def_user, pd->rec.user, BUF_MAX);

      count = mem_count(pd->rec.data, ',');
      if(2 < count && count < ((int)strlen(pd->rec.data) - 2)){
         pd->rec.ver = safe_memcpy(pd->rec.ver, strtok_r(pd->rec.data, ",", &tmp), BUF_MAX);
         pd->rec.info = safe_memcpy(pd->rec.info, strtok_r(NULL, ",", &tmp), BUF_MAX);
         }
      else{
         pd->rec.ver = safe_memcpy(pd->rec.ver, "NON", BUF_MAX);
         pd->rec.info = safe_memcpy(pd->rec.info, pd->rec.data, BUF_MAX);
         }

      pd->mail.server = safe_memcpy(pd->mail.server, gd.md.ch_MailServ, BUF_MAX);
      pd->mail.rcptto = safe_memcpy(pd->mail.rcptto, gd.md.ch_MailRcptTo, BUF_MAX);
      pd->mail.from = safe_memcpy(pd->mail.from, gd.md.ch_MailFrom, BUF_MAX);
      pd->mail.cc = safe_memcpy(pd->mail.cc, gd.md.ch_MailCc, BUF_MAX);

      pd->life.life_int = gd.bs.life_int;
      pd->life.life_los = gd.bs.life_los; 
      pd->life.onoff = 1;                    // life default on

      pd->file.bat_filename = filename_create(pd->file.bat_filename, gd.fp.file_conf, ".command", pd->rec.user);

      #ifdef DEBUG
      printf("DEBUG: neg_logi(): bat_filename <%s>\n", pd->file.bat_filename);
      #endif

      pd->file.scan_filename = filename_create(pd->file.scan_filename, gd.fp.file_conf, ".list", pd->rec.user);

      #ifdef DEBUG
      printf("DEBUG: neg_logi(): scan_filename <%s>\n", pd->file.scan_filename);
      #endif

      pd->file.conf_filename = filename_create(pd->file.conf_filename, gd.fp.file_conf, ".conf", pd->rec.user);

      #ifdef DEBUG
      printf("DEBUG: neg_logi(): conf_filename <%s>\n", pd->file.conf_filename);
      #endif

      pd->file.stat_filename = filename_create(pd->file.stat_filename, gd.fp.file_conf, ".stat", pd->rec.user);

      #ifdef DEBUG
      printf("DEBUG: neg_logi(): stat_filename <%s>\n", pd->file.stat_filename);
      #endif


      if(gd.cron_onoff == 1){
         pd->file.cronfile_filename = filename_create(pd->file.cronfile_filename, gd.fp.file_conf, ".cronfile", pd->rec.user);

         #ifdef DEBUG
         printf("DEBUG: neg_logi(): conf_filename <%s>\n", pd->file.cronfile_filename);
         #endif

         pd->file.cronlist_filename = filename_create(pd->file.cronlist_filename, gd.fp.file_conf, ".cronlist", pd->rec.user);

         #ifdef DEBUG
         printf("DEBUG: neg_logi(): conf_filename <%s>\n", pd->file.cronlist_filename);
         #endif
         }


      #ifdef LOG_OUT
      safe_pthread_mutex_lock(&con_mutex);
      log_out(gd.fp.con_fd, pd->rec.user, pd->rec.com, pd->rec.data,
        "It was newly connected.", (unsigned char *)gd.ms.inip_addr[pd->rec.fdno]);
      pthread_mutex_unlock(&con_mutex);
      #endif

      #ifdef POSTGRES_IN
      char * pgerrlog_table = "(cip,cname,monitor,uct,ye,mo,da,ha,mi,se,sign,proto,com,cinfo,port,wtime,pinfo,errdata,prino,free1,free2,free3,free4)"; 
      char * swap = (char *)calloc(2, sizeof(char));
      swap = safe_sprintf(swap, BUF_MAX, "%s%s%s('%s','%s','%s','%ld','%ld','%ld','%ld','%ld','%ld','%ld','%ld','%s','%s','%s','%ld','%ld','%s','%s','%ld','%s','%s','%s','%s');",
        "INSERT INTO errlog ",
        pgerrlog_table,
        " VALUES ",
        gd.ms.inip_addr[pd->rec.fdno],
        pd->rec.user,
        "CONNECT",
        (long int)time(NULL),
        ctime_getr('y'),
        ctime_getr('m'),
        ctime_getr('d'),
        ctime_getr('h'),
        ctime_getr('i'),
        ctime_getr('s'),
        0,
        "NOT",
        "NOT",
        "NOT",
        0,
        0,
        pd->rec.info,
        "sitar client new connection.",
        1,
        "NON",
        "NON",
        "NON",
        "NON");

      #ifdef POSTGRES_DEBUG
      printf("POSTGRES_DEBUG: neg_logi(): %s\n", swap);
      #endif

      safe_pthread_mutex_lock(&pg_mutex);
      psqlexec_datain(pd, swap);
      pthread_mutex_unlock(&pg_mutex);
      free(swap);
      #endif



      #ifdef MYSQL_IN
      char * myerrlog_table = "(cip,cname,monitor,uct,ye,mo,da,ha,mi,se,sign,proto,com,cinfo,port,wtime,pinfo,errdata,prino,free1,free2,free3,free4)"; 
      char * myswap = (char *)calloc(2, sizeof(char));
      myswap = safe_sprintf(myswap, BUF_MAX, "%s%s%s('%s','%s','%s','%ld','%ld','%ld','%ld','%ld','%ld','%ld','%ld','%s','%s','%s','%ld','%ld','%s','%s','%ld','%s','%s','%s','%s');",
        "INSERT INTO errlog ",
        myerrlog_table,
        " VALUES ",
        gd.ms.inip_addr[pd->rec.fdno],
        pd->rec.user,
        "CONNECT",
        (long int)time(NULL),
        ctime_getr('y'),
        ctime_getr('m'),
        ctime_getr('d'),
        ctime_getr('h'),
        ctime_getr('i'),
        ctime_getr('s'),
        0,
        "NOT",
        "NOT",
        "NOT",
        0,
        0,
        pd->rec.info,
        "sitar client new connection.",
        1,
        "NON",
        "NON",
        "NON",
        "NON", ' ');

      #ifdef MYSQL_DEBUG
      printf("MYSQL_DEBUG: neg_logi(): %s\n", myswap);
      #endif

      safe_pthread_mutex_lock(&mysql_mutex);
      mysqlexec_datain(myswap);
      pthread_mutex_unlock(&mysql_mutex);
      free(myswap);
      #endif



      #ifndef BIG_WOOD

      if(gd.md.in_mailonoff == 1){
         swapsubject = (char *)calloc(IP_LEN, sizeof(char));
         swapdata = (char *)calloc(IP_LEN, sizeof(char));

         // subject を作ります
         #ifdef SERVICES_MODE
         swapsubject = safe_sprintf(swapsubject, BUF_MAX, "ZITHER Watchdog <%s> %s", pd->rec.def_user, "new connection");
         #else
         swapsubject = safe_sprintf(swapsubject, BUF_MAX, "ZITHER <%s> %s", pd->rec.def_user, "new connection");
         #endif

         // 本文をつくります
         swapdata = safe_sprintf(swapdata, BUF_MAX, "%s\n\n%s\n\n%s\n", pd->rec.info, CLIENT_BODY_5, CL_VAR);
         swap_mem(swapdata, '\n', (char)0x01);

         mail_grsend(pd->mail.server,
                  pd->mail.from,
                  pd->mail.rcptto,
                  pd->mail.cc,
                  swapdata, 
                  swapsubject,
                  "NOT",
                  "1");


         free(swapsubject);
         free(swapdata);
         }

      #endif


      sostat = socket_send(gd.ms.sk[pd->rec.fdno], "200 OK\n", gd.bs.life_int);

      if(sostat < 0){
         stat = 0;
         printf("neg_logi(): 認証したがSOCKETに異常 stat = %d\n", stat);
         }

      } 
   else {
      fprintf(stderr,"neg_logi(): This account is used.\n");
      socket_send(gd.ms.sk[pd->rec.fdno],"500 NG This account is used.\n", gd.bs.life_int);
      stat = -1;
      return(stat);
      }
   }
else {
   fprintf(stderr,"neg_logi(): The permission is illegal.\n");
   socket_send(gd.ms.sk[pd->rec.fdno],"500 NG No User&IP!\n", gd.bs.life_int);
   stat = -1;
   return(stat);
   }

return(stat);
}





