
// Mysql チェック用コマンド

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

#include<sys/stat.h>
#include<errno.h>

#include"sitar_scan.h"
#include"sitar_com.h"
#include <almemsys/almemsys.h>
#include"jpreturn.h"
#include "version.h"

#include<mysql.h>

// DE BUG 用
// #define MYSQL_BUG


int main(int argc, char * argv[])
{
char i;

MYSQL mysql_buf;
MYSQL * my_conn;
MYSQL_RES * my_res;

int port;
int timeout;
int db_select;
char * database;
char * passwd;
char * username;
char * server;
char * query;
char * dns_data;
extern char *optarg;

port = 3306;
timeout = 1;
db_select = 0;

if((database = (char *)calloc(BUF_LEN, sizeof(char)))==NULL){ exit(1);}
if((passwd = (char *)calloc(BUF_LEN, sizeof(char)))==NULL){ exit(1);}
if((username = (char *)calloc(BUF_LEN, sizeof(char)))==NULL){ exit(1);}
if((server = (char *)calloc(BUF_LEN, sizeof(char)))==NULL){ exit(1);}
if((query = (char *)calloc(BUF_LEN, sizeof(char)))==NULL){ exit(1);}
if((dns_data = (char *)calloc(BUF_LEN, sizeof(char)))==NULL){ exit(1);}

// defaultのDNSを設定
dns_data = safe_memcpy(dns_data, "127.0.0.1", 1024);

// optionの処理
while((i=getopt(argc,argv,"y:p:P:d:u:s:q:t:o"))!= EOF){
   switch(i){
      case 'P': if(0 == ch_int2(optarg)){
                   port = strtol(optarg, (char **)NULL, 10);
                   }
              break;
      case 't': if(0 == ch_int2(optarg)){
                   timeout = strtol(optarg, (char **)NULL, 10);
                   }
              break;
      case 'p': if(optarg != NULL){
                   passwd = safe_memcpy(passwd, optarg, 256);
                   }
                else{
                   passwd = safe_memcpy(passwd, "", 2);
                   }
              break;
      case 'd': if(optarg != NULL){
                   database = safe_memcpy(database, optarg, 256);
                   db_select = 1;
                   }
                else{
                   database = safe_memcpy(database, "", 256);
                   db_select = 0;
                   }
              break;
      case 'u': if(optarg != NULL){
                   username = safe_memcpy(username, optarg, 256);
                   }
                else{
                   username = safe_memcpy(username, "mysql", 256);
                   }
              break;
      case 's': if(optarg != NULL){
                   server = safe_memcpy(server, optarg, 256);
                   }
                else{
                   server = safe_memcpy(server, "127.0.0.1", 256);
                   }
              break;
      case 'q': if(optarg != NULL){
                   query = safe_memcpy(query, optarg, 256);
                   }
                else{
                   query = safe_memcpy(query, "SHOW DATABASES;", 256);
                   }
              break;


      default : printf("scanmysql-%s $scanmysql -t <timeout> -s <server> -u <username> -p <passwd> -d <database> -P <port> -q <query>\n",VERSION);
              free(database);
              free(passwd);
              free(username);
              free(server);
              free(query);
              exit(1);
              break;
      }
   }


if(0 == strlen(query)){
   query = safe_memcpy(query, "show databases;", 256);
   }

//if(0 == strlen(server)){
//   server = safe_memcpy(server, "127.0.0.1", 256);
//   }


#ifdef MYSQL_BUG
printf("MYSQL_BUG: scanmysql main():\n server=<-s %s>\n username=<-u %s>\n passwd=<-p %s>\n database=<-d %s>\n port=<-P %d>\n query=<-q %s> timeout=<-t %d>\n",
        server,
        username,
        passwd,
        database,
        port,
        query,
        timeout);
#endif


// 初期化とタイムアウトの設定
mysql_init(&mysql_buf);
mysql_options(&mysql_buf, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&timeout);
mysql_options(&mysql_buf, MYSQL_OPT_READ_TIMEOUT, (const char *)&timeout);
mysql_options(&mysql_buf, MYSQL_OPT_WRITE_TIMEOUT, (const char *)&timeout);

my_conn = mysql_real_connect(&mysql_buf, server, username, passwd, database, port, "/var/run/mysqld/mysqld.sock", 0);

// mysql に接続出来たかの確認　出来ない場合は終了
if(my_conn == NULL){
   printf("mysql_real_connect(): %s\n", mysql_error(&mysql_buf));
   free(database);
   free(passwd);
   free(username);
   free(server);
   free(query);
   exit(1);
   }

 
// データベースが選択されている場合のみデータベースが選択出来るか
if(db_select == 1){
   if(mysql_select_db(&mysql_buf, database) != 0) {
      printf("mysql_select_db(): %s\n", mysql_error(&mysql_buf));
      free(database);
      free(passwd);
      free(username);
      free(server);
      free(query);
      mysql_close(&mysql_buf);
      exit(1);
      }
   }


// 正常に問い合わせが出来るか
if(mysql_query(&mysql_buf, query) != 0) {
   printf("mysql_query(): %s\n", mysql_error(&mysql_buf));
   free(database);
   free(passwd);
   free(username);
   free(server);
   free(query);
   mysql_close(&mysql_buf);
   exit(1);
   }

// バッファに展開が出来るのか
if((my_res = mysql_store_result(&mysql_buf))){
   // レコード数が0かそれ以下の場合
   if(1 > mysql_num_rows(my_res)){
      printf("mysql_num_rows(): 0 record  %s\n", mysql_error(&mysql_buf));
      mysql_free_result(my_res);
      free(database);
      free(passwd);
      free(username);
      free(server);
      free(query);
      mysql_close(&mysql_buf);
      exit(1);
      }

   if(0 < mysql_warning_count(&mysql_buf)){
      printf("mysql_warning_count(): %s\n", mysql_error(&mysql_buf));
      mysql_free_result(my_res);
      free(database);
      free(passwd);
      free(username);
      free(server);
      free(query);
      mysql_close(&mysql_buf);
      exit(1);
      }


#ifdef MYSQL_BUG
 printf("rows=%d err=%d\n", mysql_num_rows(my_res), mysql_warning_count(&mysql_buf));
#endif

   mysql_free_result(my_res);
   }
else{
   printf("mysql_store_result(): %s\n", mysql_error(&mysql_buf));
   free(database);
   free(passwd);
   free(username);
   free(server);
   free(query);
   mysql_close(&mysql_buf);
   exit(1);
   }

if(&mysql_buf){
   mysql_close(&mysql_buf);
   }

free(database);
free(passwd);
free(username);
free(server);
free(query);

return 0;
}




