
#include<stdio.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/socket.h>
#include<netinet/in_systm.h>
#include<netinet/in.h>
#include<netinet/ip.h>
#include<arpa/inet.h>
#include<stdlib.h>
#include<string.h>
#include<pthread.h>
#include<time.h>
#include<errno.h>

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


extern global_data_t gd;

// V6 対応

// zither main()カラ最初ニ分岐スルスレッド
int connect_open(int fdno)
{
int stat, ret, neg;
private_data_t *pd;

stat = 0;
ret = 0;
neg = 0;

char * swapsubject = (char *)calloc(BUF_DEFLEN, sizeof(char));
char * swapdata = (char *)calloc(BUF_DEFLEN, sizeof(char));

if((pd = (private_data_t *)malloc(sizeof(private_data_t)))==NULL){exit(1);}
private_malloc_set(pd);
pd->rec.fdno = fdno;

pthread_detach(pthread_self());

/*  Processing description as follows  */

pd->getdata = select_fdcat(gd.ms.sk[pd->rec.fdno], pd->getdata, &stat, BUF_MAX, 15);

if(stat >= 0){
   neg = start_neg(pd);
   #ifdef DATA_SIZE
   printf("DATA_SIZE: connect_open(): start_neg %d\n", neg);
   #endif
   // 認証を通過した場合
   if(neg >= 1){
      #ifdef POSTGRES_IN
      psql_connectset(pd, "ON");
      #endif
      #ifdef MYSQL_IN
      mysql_connectset(pd, "ON");
      #endif
      for(;ret >= 0;){
         pd->getdata = select_fdcat(gd.ms.sk[pd->rec.fdno], pd->getdata, &ret, BUF_MAX,
                                     (pd->life.life_int + pd->life.life_los + 15));
         #ifdef DATA_SIZE
         printf("DATA_SIZE: connect_open(): select_fdcat stat %d\n", ret);
         #endif
         if(ret >= 0){
            ret = stag_neg(pd);
            #ifdef DATA_SIZE
            printf("DATA_SIZE: connect_open(): stag_neg stat %d neg %d\n", ret, neg);
            #endif
            }
         } /* for */
      }
   }
else{
   #ifdef THREAD_BUG
   fprintf(stderr,"THREAD_BUG: connect_open(): 正常に認証を通過しない接続なのでスレッドを破棄します fdn = %d\n",
      pd->rec.fdno);
   #endif

   safe_pthread_mutex_lock(&stat_mutex);
   gd.ms.fdstat[pd->rec.fdno] = 0;
   pthread_mutex_unlock(&stat_mutex);

   close(gd.ms.sk[pd->rec.fdno]);
   private_malloc_free(pd);
   free(pd);
   free(swapsubject);
   return 0;
   }


/*  Here  */

#ifdef THREAD_BUG
fprintf(stderr,"THREAD_BUG: connect_open(): スレッド番号.%d　がデタッチされました\n", fdno);
#endif

fprintf(stdout,"connect_open(0): break loop or not connection. FD=%d USER=%s\n", pd->rec.fdno, pd->rec.user);
fprintf(stdout,"connect_open(1): break loop life.cancel no is ->%d\n", pd->life.cancel);

if(pd->life.in_life[0] > 0){
   pd->life.cancel = -1;
   fprintf(stderr,"connect_open(3): The thread is canceled. FD=%d USER=%s\n",  pd->rec.fdno, pd->rec.user);
   }

// 認証を通過した場合
//if(neg >= 1){
if(neg >= 0){

   #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,
      "CLOSE",
      (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 shutdown.",
      1,
      "NON",
      "NON",
      "NON",
      "NON");

   safe_pthread_mutex_lock(&pg_mutex);
   psqlexec_datain(pd, swap);
   pthread_mutex_unlock(&pg_mutex);
   #ifdef POSTGRES_DEBUG
   printf("POSTGRES_DEBUG: connect_open(): >>%s\n", swap);
   #endif

   psql_connectset(pd, "OFF");

   free(swap);
   #endif   /* POSTGRES_IN */


   #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,
      "CLOSE",
      (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 shutdown.",
      1,
      "NON",
      "NON",
      "NON",
      "NON");

   safe_pthread_mutex_lock(&mysql_mutex);
   mysqlexec_datain(myswap);
   pthread_mutex_unlock(&mysql_mutex);

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

   mysql_connectset(pd, "OFF");

   free(myswap);
   #endif   /* MYSQL_IN */



   if(gd.md.in_mailonoff == 1){
      if(0 == self_memcmp(pd->rec.def_user, "administrator")){

         // subject を作ります
         swapsubject = make_subject(swapsubject, ADMIN_BODY_2, pd->rec.def_user);

         // 本文をつくります
         swapdata = safe_sprintf(swapdata, BUF_MAX, "%s\n\n%s\n\n%s\n", pd->rec.info, ADMIN_BODY_1, 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");
         }
      else{

         // subject を作ります
         swapsubject = make_subject(swapsubject, CLIENT_BODY_2, pd->rec.def_user);

         // 本文をつくります
         swapdata = safe_sprintf(swapdata, BUF_MAX, "%s\n\n%s\n\n%s\n", pd->rec.info, CLIENT_BODY_1, 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");
         }
     }


   #ifdef LOG_OUT
   safe_pthread_mutex_lock(&con_mutex);
   log_out(gd.fp.con_fd, pd->rec.user, pd->rec.com, pd->rec.data,
     "Zither server connection is lost.", (unsigned char *)gd.ms.inip_addr[pd->rec.fdno]);
   pthread_mutex_unlock(&con_mutex);
   #endif

   sleep(2);

   fprintf(stderr,"connect_open(4-1): removd %s lock file\n", pd->file.clock_filename);
   lock_remove(pd->file.lock_filename);
   pd->file.clock_filename = chack_lockfile(pd->rec.user, pd->rec.info, pd->file.clock_filename, gd.fp.clock_path, &stat);
   if(0 == self_memcmp(pd->rec.user, "administrator")){
      lock_remove(pd->file.clock_filename);
      fprintf(stderr,"connect_open(4-2): removd administrator lock file <%s>\n", pd->file.clock_filename);
      }

   } /* neg stat >= 0 */

safe_pthread_mutex_lock(&stat_mutex);
gd.ms.fdstat[pd->rec.fdno] = 0;
pthread_mutex_unlock(&stat_mutex);

close(gd.ms.sk[pd->rec.fdno]);

fprintf(stderr,"connect_open(5): thread Management number %d fd openings. <%s>\n",
   pd->rec.fdno, pd->rec.user);
fprintf(stderr,"connect_open(6): thread Management number %d plivate memory openings. <%s>\n",
   pd->rec.fdno, pd->rec.user);


private_malloc_free(pd);
free(pd);
free(swapsubject);
free(swapdata);

return 0;
}







