
// scan_block_test

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

#include"sitar.h"
#include"sitar_com.h"
#include<almemsys/almemsys.h>
#include"jpreturn.h"
#include<file_comp/file_comp.h>


// #define MONITOR_BUG

global_data_t gd;

pthread_mutex_t exec_mutex;
// pthread_mutex_t popen_mutex;
pthread_mutex_t name_mutex;

//  scan_block はポート、コマンドのスレッド分岐先の関数になります
int main(int argc, char ** argv)
{
int dstat, mode, i, fds;
char mid_stat;
extern char *optarg;

if((gd.di.dns_name = (char *)calloc(IP_LEN, sizeof(char)))==NULL){ m_exit(1);}
gd.di.dns_name = safe_memcpy(gd.di.dns_name, "127.0.0.1", BUF_MAX);

mid_stat = 0;
dstat = 0;
mode = 0;

pthread_mutex_init(&name_mutex, NULL);
pthread_mutex_init(&exec_mutex, NULL);
// pthread_mutex_init(&popen_mutex, NULL);

// バッファーの確保と初期化
private_data_t *pd;

if((pd = (private_data_t *)malloc(sizeof(private_data_t)))==NULL){exit(1);}
scan_malloc_set(pd);

if((fds = getdtablesize()) <= 0){
   fprintf(stderr,"p_open(): not get fd size.\n");
   fds = 1024;
   }

//for(co = 0; co < COM_LEN; co++){
//   pids[co] = (int *)malloc((u_int)(fds * sizeof(int)));
//   }



// optionの処理
while((i=getopt(argc,argv,"a:d:r:m:v"))!= EOF){
   switch(i){
      case 'm': if(0 == ch_int2(optarg)){
                   mode = strtol(optarg, (char **)NULL, 10);
                   }
              break;
      case 'd': if(optarg != NULL){
                   pd->sb.swap_2 = safe_memcpy(pd->sb.swap_2, optarg, 1024);
                   }
                else{
                   pd->sb.swap_2 = safe_memcpy(pd->sb.swap_2, "NOT_DATA", 1024);
                   }
              break;
      case 'r': if(optarg != NULL){
                   gd.di.dns_name = safe_memcpy(gd.di.dns_name, optarg, BUF_MAX);
                   }
                else{
                   gd.di.dns_name = safe_memcpy(gd.di.dns_name, "127.0.0.1", BUF_MAX);
                   }
              break;

      default : printf("scan_block_test-%s $scan_bloc_test -d <monitor_data> -m <0-1> -r <dns ip address>\n",VERSION);
//           for(co = 0; co < COM_LEN; co++){
//              free(pids[co]);
//              }
              scan_malloc_free(pd);
              free(pd);
              exit(1);
              break;
      }
   }


// 先頭からむが'#'ではない
if('#' != pd->sb.swap_2[0]){ 
   // ','が13個
   if(13 == char_count(pd->sb.swap_2,',')){ 
      // 13文字上ある
      if(13 <= strlen(pd->sb.swap_2) || 1024 > strlen(pd->sb.swap_2)){ 

         pd->sb.ch_tool = delim_get(pd->sb.swap_2, pd->sb.ch_tool, ',', &dstat, 0);
         pd->sb.ch_stat = delim_get(pd->sb.swap_2, pd->sb.ch_stat, ',', &dstat, 1);
         pd->sb.ch_prot = delim_get(pd->sb.swap_2, pd->sb.ch_prot, ',', &dstat, 2);
         pd->sb.ch_com = delim_get(pd->sb.swap_2, pd->sb.ch_com, ',', &dstat, 3);
         pd->sb.ch_host = delim_get(pd->sb.swap_2, pd->sb.ch_host, ',', &dstat, 4);
         pd->sb.ch_port = delim_get(pd->sb.swap_2, pd->sb.ch_port, ',', &dstat, 5);
         pd->sb.ch_timeout = delim_get(pd->sb.swap_2, pd->sb.ch_timeout, ',', &dstat, 6);
         pd->sb.ch_data = delim_get(pd->sb.swap_2, pd->sb.ch_data, ',', &dstat, 7);
         pd->sb.ch_plai = delim_get(pd->sb.swap_2, pd->sb.ch_plai, ',', &dstat, 8);
         pd->sb.ch_free1 = delim_get(pd->sb.swap_2, pd->sb.ch_free1, ',', &dstat, 9);
         pd->sb.ch_free2 = delim_get(pd->sb.swap_2, pd->sb.ch_free2, ',', &dstat, 10);
         pd->sb.ch_free3 = delim_get(pd->sb.swap_2, pd->sb.ch_free3, ',', &dstat, 11);
         pd->sb.ch_free4 = delim_get(pd->sb.swap_2, pd->sb.ch_free4, ',', &dstat, 12);

         #ifdef BLOCK_TEST_BUG
         // 入ってきた内容をきれいに?してバッファーに入れる
         pd->sb.swap = safe_sprintf(pd->sb.swap, BUF_MAX,
         "%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s",
           pd->sb.ch_tool,
           pd->sb.ch_stat,
           pd->sb.ch_prot,
           pd->sb.ch_com,
           pd->sb.ch_host,
           pd->sb.ch_port,
           pd->sb.ch_timeout,
           pd->sb.ch_data,
           pd->sb.ch_plai,
           pd->sb.ch_free1,
           pd->sb.ch_free2,
           pd->sb.ch_free3,
           pd->sb.ch_free4);
         printf("%s\n", pd->sb.swap);
         #endif

         // すべての読み込みデータが0でないことの確認
         if(1 <= strlen(pd->sb.ch_stat) && 1 <= strlen(pd->sb.ch_prot) &&
            1 <= strlen(pd->sb.ch_host) && 1 <= strlen(pd->sb.ch_port) &&
            1 <= strlen(pd->sb.ch_timeout) && 1 <= strlen(pd->sb.ch_data) &&
            1 <= strlen(pd->sb.ch_tool) && 1 <= strlen(pd->sb.ch_com) &&
            1 <= strlen(pd->sb.ch_plai) && 1 <= strlen(pd->sb.ch_free1)){ 

            rm_crlf(pd->sb.ch_stat, strlen(pd->sb.ch_stat));
            rm_crlf(pd->sb.ch_prot, strlen(pd->sb.ch_prot));
            rm_crlf(pd->sb.ch_host, strlen(pd->sb.ch_host));
            rm_crlf(pd->sb.ch_port, strlen(pd->sb.ch_port));
            rm_crlf(pd->sb.ch_timeout, strlen(pd->sb.ch_timeout));
            rm_crlf(pd->sb.ch_data, strlen(pd->sb.ch_data));
            rm_crlf(pd->sb.ch_tool, strlen(pd->sb.ch_tool)); 
            rm_crlf(pd->sb.ch_com, strlen(pd->sb.ch_com)); 
            rm_crlf(pd->sb.ch_plai, strlen(pd->sb.ch_plai)); 
            rm_crlf(pd->sb.ch_free1, strlen(pd->sb.ch_free1));
            rm_crlf(pd->sb.ch_free2, strlen(pd->sb.ch_free2));
            rm_crlf(pd->sb.ch_free3, strlen(pd->sb.ch_free3));
            rm_crlf(pd->sb.ch_free4, strlen(pd->sb.ch_free4));


            // 一からむ目がSETでない場合はtimeoutを数字に変換
            if(0 != self_memcmp(pd->sb.ch_tool, "SET")){

               pd->sb.port = strtol(pd->sb.ch_port, (char **)NULL, 10);
               pd->sb.timeout = strtol(pd->sb.ch_timeout, (char **)NULL, 10);

               if(pd->sb.timeout > TIME_OUT || pd->sb.timeout < 0){
                  if(pd->sb.timeout > TIME_OUT){
                     pd->sb.timeout = 4;
                     }
                  else{
                     pd->sb.timeout = 0;
                     }
                  }

               }


            // SET は最初の行に限定される条件なので、最初に以下の監視条件を満たすことは無いです。
            pd->sb.ch_info = safe_memcpy(pd->sb.ch_info, "\n", BUF_MAX);

            if(0 == self_memcmp(pd->sb.ch_tool, "PORT")){
               #ifdef MONITOR_BUG
               fprintf(stderr,"MONITOR 1: %s: %s: %s: %s:\n",
                 pd->sb.ch_tool, pd->sb.ch_prot, pd->sb.ch_free1, pd->sb.ch_free4);
               #endif 
//             scan_port(&pd->sb);
               scan_port(pd);
               }
            else if(0 == self_memcmp(pd->sb.ch_tool, "COMAND")){
               #ifdef MONITOR_BUG
               fprintf(stderr,"MONITOR 2: %s: %s: %s: %s:\n",
                 pd->sb.ch_tool, pd->sb.ch_com, pd->sb.ch_free1, pd->sb.ch_free4);
               #endif 
               scan_comand(pd);
               }
            else if(0 == self_memcmp(pd->sb.ch_tool, "SNMP")){
               #ifdef MONITOR_BUG
               fprintf(stderr,"MONITOR 3: %s: %s: %s: %s:\n",
                 pd->sb.ch_tool, pd->sb.ch_prot, pd->sb.ch_free1, pd->sb.ch_free4);
               #endif 
               scan_snmp(&pd->sb);
               }
/*          else if(0 == self_memcmp(pd->sb.ch_tool, "SET")){
               #ifdef MONITOR_BUG
               fprintf(stderr,"MONITOR 4: %s: %s: %s: %s:\n",
                 pd->sb.ch_tool, pd->sb.ch_prot, pd->sb.ch_free1, pd->sb.ch_free4);
               #endif 
               pd->sb.check_stat = 2;
               } */
            else{
               #ifdef MONITOR_BUG
               fprintf(stderr,"MONITOR 5: scan_block(): 存在しない監視属性が設定されています %s: %s: %s: %s:\n",
                 pd->sb.ch_tool, pd->sb.ch_prot, pd->sb.ch_free1, pd->sb.ch_free4);
               #endif 

               pd->sb.ch_info = safe_sprintf(pd->sb.ch_info, BUF_MAX,"%s : %s : %s : %s : %s\n",
                 MONITOR_ERR_1, pd->sb.ch_tool, pd->sb.ch_prot, pd->sb.ch_free1, pd->sb.ch_free4);
               pd->sb.check_stat = 1;
               pd->sb.ch_plai = safe_memcpy(pd->sb.ch_plai, "6", BUF_MAX); 

               }


/*            // SET 行の場合の処理になります
            if(pd->sb.check_stat == 2 ){
               printf("OK : SET LINE : %s\n", pd->sb.swap_2);
               }  // SET の処理最後   */


            // ERR が観測された場合の処理。
            if(pd->sb.check_stat == 1){
               if(mode == 0){
                  swap_mem(pd->sb.ch_info, ';', ' ');
                  printf("ERR: %s\n", pd->sb.ch_info);
                  }
               else if(mode == 1){
                  swap_mem(pd->sb.ch_info, ';', ' ');
                  printf("%s: %s\n", BLOCK_TEST_6, pd->sb.ch_info);
                  }
               else{
                  printf("ERR: %s : %s\n", pd->sb.swap_2, pd->sb.ch_info);
                  }
               } // ERRな場合の最後


            // ERR が観測されない場合の処理
            else if(pd->sb.check_stat == 0){
               if(mode == 0){
                  swap_mem(pd->sb.ch_info, ';', ' ');
                  printf("OK : %s\n", pd->sb.ch_info);
                  }
               else if(mode == 1){
                  swap_mem(pd->sb.ch_info, ';', ' ');
                  printf("%s: %s\n", BLOCK_TEST_5, pd->sb.ch_info);
                  }
               else{
                  printf("OK: %s : %s\n", pd->sb.swap_2, pd->sb.ch_info);
                  }
               } // ERRでない場合の最後


            // それ以外の場合
            else{
               printf("NG: %s = %s return = %s\n", BLOCK_TEST_7, pd->sb.swap_2, pd->sb.ch_info);
               } // ERRでない場合の最後



            }  // すべての読み込みデータが0でないことの確認 
         else{
            printf("%s\n", BLOCK_TEST_1);
            }
         }  // 13文字以上ある
      else{
         printf("%s <%d>\n", BLOCK_TEST_2, strlen(pd->sb.swap_2));
         }
      }  // ','が13個以下か以上
   else{
      printf("%s <%d>\n", BLOCK_TEST_3, char_count(pd->sb.swap_2,','));
      }
   }  // 先頭からむが'#'の場合
else{
   printf("%s\n", BLOCK_TEST_4);
   }


// メモリーの開放
//  for(co = 0; co < COM_LEN; co++){
//    free(pids[co]);
//    }
scan_malloc_free(pd);
free(pd);
free(gd.di.dns_name);


return 0;
}




