Files
interactive/gms/neo_statusd/src/check_neocast.c
T
2026-08-07 17:38:18 +09:00

477 lines
14 KiB
C

#include "check_neocast.h"
#include "protocol.h"
#include "cfgconfig.h"
#include "util.h"
#include <signal.h>
#include <sys/wait.h>
#include <sys/signal.h>
extern int dig_func(int , char **, int *, int *);
extern int Tcp_connect(const char *, const char *);
extern void Send(int, const void *, size_t, int);
extern ssize_t Recv(int, void *, size_t, int);
static char hexchars[] = "0123456789ABCDEF";
void safe_wait()
{
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 100;
select(0, NULL, NULL, NULL, &tv);
}
#define STAT_STAMP(a) (((a) + (stat_term - 1)) / stat_term)
void loop_check()
{
int ret_val = 0;
int stat_term;
time_t now, past;
unsigned long past_stamp = 0;
unsigned long now_stamp = 0;
SetIniName(CFGFILE);
stat_term = GetProfileInt("STAT_TERM", 60);
now = past = time(NULL);
now_stamp = past_stamp = STAT_STAMP(now);
for( ; ; ) {
now = time(NULL);
now_stamp = STAT_STAMP(now);
if (past != now) {
// whenever 1 minutes (60 seconds)
ret_val = check_neocast(now, &now_stamp, &past_stamp);
if (ret_val == 1)
{
past = now = time(NULL);
now_stamp = past_stamp = STAT_STAMP(now);
}
}
safe_wait();
}
}
int check_neocast(time_t now, unsigned long *now_stamp, unsigned long *past_stamp)
{
FILE *shLogFile = NULL;
struct tm *t;
neo_serv_info *nserv_info, *temp_info;
MYSQL mysql, child_mysql;
MYSQL_RES *res;
MYSQL_ROW row;
int i;
int mysql_port, fields;
long numRows;
long cnt = 0;
char mysql_db[8];
char mysql_user[16];
char mysql_pass[16];
char logString[1024];
/* check time */
if (*now_stamp == *past_stamp)
return 0;
/* sh log file open */
shLogFile = fopen(makeLogString(), "a");
if (!shLogFile)
{
fprintf(stderr, "Cannot open SH Log file!!\n");
exit(EXIT_FAILURE);
}
/***********************************************************************************************************/
/* initialize mysqlDB */
mysql_init(&mysql);
mysql_init(&child_mysql);
// get mysql info
SetIniName(CFGFILE);
GetProfile("DATABASE_NAME", mysql_db, "CCDB");
GetProfile("DATABASE_ACCT", mysql_user, "root");
GetProfile("DATABASE_PW", mysql_pass, "alfkzmf!?{}");
mysql_port = GetProfileInt("DATABASE_PORT", 3306);
fprintf(stderr, "DATABASE_NAME : %s\n", mysql_db);
fprintf(stderr, "DATABASE_ACCT : %s\n", mysql_user);
fprintf(stderr, "DATABASE_PW : %s\n", mysql_pass);
fprintf(stderr, "DATABASE_PORT : %d\n", mysql_port);
/* connect mysqlDB */
if (!mysql_real_connect(&mysql, NULL, mysql_user, mysql_pass, mysql_db, mysql_port, (char *)NULL, 0))
{
fprintf(stderr, "parent mysql: %s\n", mysql_error(&mysql));
snprintf(logString, 1024, "%s", mysql_error(&mysql));
WriteSHLog(logString, shLogFile);
exit(EXIT_FAILURE);
}
if (!mysql_real_connect(&child_mysql, NULL, mysql_user, mysql_pass, mysql_db, mysql_port, (char *)NULL, 0))
{
fprintf(stderr, "%s\n", mysql_error(&child_mysql));
snprintf(logString, 1024, "child mysql: %s", mysql_error(&child_mysql));
WriteSHLog(logString, shLogFile);
exit(EXIT_FAILURE);
}
/***********************************************************************************************************/
/* autocommit on */
mysql_autocommit(&child_mysql, 1);
snprintf(logString, 1024, "Query to get arranged Server List :: %s", MYQUERY);
WriteSHLog(logString, shLogFile);
if (mysql_query(&mysql, MYQUERY) < 0)
{
snprintf(logString, 1024, "[error]%s", mysql_error(&mysql));
WriteSHLog(logString, shLogFile);
exit(EXIT_FAILURE);
}
else
{
snprintf(logString, 1024, "%s", "[MySQL]Server List Loading Success!!");
WriteSHLog(logString, shLogFile);
}
res = mysql_store_result(&mysql);
fields = mysql_num_fields(res);
numRows = mysql_num_rows(res);
snprintf(logString, 1024, "numRows --> %ld", numRows);
WriteSHLog(logString, shLogFile);
neo_serv_num = numRows;
nserv_info = (neo_serv_info *)malloc(sizeof(neo_serv_info));
temp_info = nserv_info;
while((row = mysql_fetch_row(res)))
{
memset(temp_info, 0, sizeof(temp_info));
temp_info->neo_seq = atol(row[0]);
strncpy(temp_info->name, row[1], MaxSizeOfServerName);
strncpy(temp_info->domain, row[2], MaxSizeOfServerAddr);
strncpy(temp_info->dig_domain, row[3], MaxSizeOfServerAddr);
strncpy(temp_info->ipaddr, row[4], MaxSizeOfServerIp);
strncpy(temp_info->type ,row[5], MaxSizeOfServerType);
temp_info->port = atoi(row[6]);
temp_info->dead_count = atoi(row[7]);
temp_info->status = atoi(row[8]);
temp_info->next = NULL;
temp_info->next = (neo_serv_info *)malloc(sizeof(neo_serv_info));
temp_info = temp_info->next;
}
temp_info = NULL;
temp_info = nserv_info;
for (cnt = 0; cnt < neo_serv_num; cnt++)
{
pid_t dpid;
int status = 0;
// check neocast STAT
if (!strcmp(temp_info->type, "STAT"))
{
char buf[1024];
int result;
// CHG 2010-10-21 huibong KT -> X-CDN
//sprintf(buf, "wget -T 10 -t 2 -q \"http://222.122.18.6/neo_status\" -O /root/neo_status");
sprintf(buf, "wget -T 10 -t 2 -q \"http://www.x-cdn.com/neo_status\" -O /root/neo_status");
WriteSHLog(buf, shLogFile);
result = system(buf);
if (result == 0)
{
FILE *fp = NULL;
char update_query[1024];
char msgStr[1024];
sprintf(buf, "/root/neo_status");
if ((fp = fopen(buf, "r")))
{
memset(buf, 0, 4);
fread(buf, 1, 3, fp);
if (buf[0] == 'O') { // wget success
WriteSHLog("[STAT SUCCESS!]", shLogFile);
if (temp_info->status == 2 || temp_info->dead_count > 0) {
snprintf(update_query, 1024, "UPDATE t_neo_server_index SET dead_count = 0, status = 1, update_datetime = now() WHERE neo_seq = %ld", temp_info->neo_seq);
WriteSHLog(update_query, shLogFile);
if (mysql_query(&child_mysql, update_query) != 0)
{
snprintf(logString, 1024, "[error]%s", mysql_error(&child_mysql));
WriteSHLog(logString, shLogFile);
exit(EXIT_FAILURE);
}
else
{
snprintf(logString, 1024, "%s", "Update STAT query Success!!");
WriteSHLog(logString, shLogFile);
}
// SMS BACK and SendToWebServ
if (temp_info->status == 2) {
snprintf(msgStr, MaxSizeOfsmsStr, "[NEO][BACK] STAT IS BACK!");
SendToWebServ(msgStr, shLogFile);
}
}
}
else if (buf[0] == 'E') {
WriteSHLog("[!STAT FAIL]", shLogFile);
// SMS DEAD and SendToWebServ
if (temp_info->dead_count >= MAX_ALLOWED_DEAD_COUNT && ((int)temp_info->dead_count < MAX_ALLOWED_DEAD_COUNT + 5)) {
snprintf(msgStr, MaxSizeOfsmsStr, "[NEO][DEAD] STAT IS ERROR!!");
snprintf(update_query, 1024, "UPDATE t_neo_server_index SET dead_count = %d, status = 2, update_datetime = now() WHERE neo_seq = %ld", temp_info->dead_count + 1, temp_info->neo_seq);
SendToWebServ(msgStr, shLogFile);
}
else {
// SMS DEAD but not SendToWebServ
snprintf(update_query, 1024, "UPDATE t_neo_server_index SET dead_count = %d, update_datetime = now() WHERE neo_seq = %ld", temp_info->dead_count + 1, temp_info->neo_seq);
}
WriteSHLog(update_query, shLogFile);
if (mysql_query(&child_mysql, update_query) != 0)
{
snprintf(logString, 1024, "[error]%s", mysql_error(&child_mysql));
WriteSHLog(logString, shLogFile);
exit(EXIT_FAILURE);
}
else
{
snprintf(logString, 1024, "%s", "Update STAT query Success!!");
WriteSHLog(logString, shLogFile);
}
}
}
if (fp)
fclose(fp);
}
}
signal(SIGCHLD, SIG_DFL);
dpid = fork();
// child must process dig func
if (dpid == 0)
{
int i;
char dig_cmd[1024];
char update_query[1024];
char msgStr[1024];
char *paraop[512];
int qrcount = 0;
int ancount = 0;
int retval = 0;
if (!strcmp(temp_info->type, "STAT"))
{
fclose(shLogFile);
exit(EXIT_SUCCESS);
}
setproctitle("grandchildren: working for digging...");
snprintf(dig_cmd, 1024, "dig @%s %s", temp_info->domain, temp_info->dig_domain);
WriteSHLog(dig_cmd, shLogFile);
paraop[0] = (char *)malloc(512);
paraop[1] = (char *)malloc(512);
paraop[2] = (char *)malloc(512);
memset(paraop[0], 0, 512);
memset(paraop[1], 0, 512);
memset(paraop[2], 0, 512);
strncpy(paraop[0], "dig", 512);
snprintf(paraop[1], 512, "@%s", temp_info->domain);
strncpy(paraop[2], temp_info->dig_domain, 512);
retval = dig_func(3, paraop, &qrcount, &ancount);
/* three case */
/* fail : invaild dns name : retval = -1, ancount = 0 */
/*fail : invalid domain name, query timout : retval = 0, ancount = 0 */
/* success : retval = 0, ancount >= 1*/
snprintf(logString, 1024, "dig result : QUERY: %d, ANSWER: %d", qrcount, ancount);
WriteSHLog(logString, shLogFile);
if (retval == -1 || (qrcount == 0 && ancount == 0))
{
//if (temp_info->dead_count >= MAX_ALLOWED_DEAD_COUNT && ((int)temp_info->dead_count < MAX_ALLOWED_DEAD_COUNT + 5)) {
//modify sindong .... 09/12/31
if (temp_info->dead_count >= 0 && ((int)temp_info->dead_count < MAX_ALLOWED_DEAD_COUNT + 5)) {
// SMS DEAD and SendToWebServ
snprintf(msgStr, MaxSizeOfsmsStr, "[NEO][DEAD] %s \n", dig_cmd);
snprintf(update_query, 1024, "UPDATE t_neo_server_index SET dead_count = %d, status = 2, update_datetime = now() WHERE neo_seq = %ld",
temp_info->dead_count + 1, temp_info->neo_seq);
SendToWebServ(msgStr, shLogFile);
}
else {
// SMS DEAD but not SendToWebServ
snprintf(update_query, 1024, "UPDATE t_neo_server_index SET dead_count = %d, update_datetime = now() WHERE neo_seq = %ld",
temp_info->dead_count + 1, temp_info->neo_seq);
}
}
else if (qrcount >= 1 && ancount >= 1)
{
if (temp_info->status == 2)
{
snprintf(update_query, 1024, "UPDATE t_neo_server_index SET dead_count = 0, status = 1, update_datetime = now() WHERE neo_seq = %ld", temp_info->neo_seq);
// SMS BACK and SendToWebServ
snprintf(msgStr, MaxSizeOfsmsStr, "[NEO][BACK] %s \n", dig_cmd);
SendToWebServ(msgStr, shLogFile);
}
else if (temp_info->status == 1 && temp_info->dead_count == 0)
goto free_exit;
else
snprintf(update_query, 1024, "UPDATE t_neo_server_index SET dead_count = 0, status = 1, update_datetime = now() WHERE neo_seq = %ld", temp_info->neo_seq);
}
else
goto free_exit;
WriteSHLog(update_query, shLogFile);
if (mysql_query(&child_mysql, update_query) != 0)
{
snprintf(logString, 1024, "[error]%s", mysql_error(&child_mysql));
WriteSHLog(logString, shLogFile);
exit(EXIT_FAILURE);
}
else
{
snprintf(logString, 1024, "%s", "Update DIG query Success!!");
WriteSHLog(logString, shLogFile);
}
free_exit:
for (i=0; i < 3; i++)
free(paraop[i]);
exit(EXIT_SUCCESS);
}
wait(&status);
temp_info = temp_info->next;
usleep(1);
}
WriteSHLog("----------------------------------------------------- end ---------------------------------------------\n", shLogFile);
*past_stamp = *now_stamp;
mysql_free_result(res);
mysql_close(&mysql);
mysql_close(&child_mysql);
fclose(shLogFile);
for (i=0; i < neo_serv_num; i++)
{
free(nserv_info);
nserv_info = nserv_info->next;
}
free(nserv_info);
return 1;
}
// CHG 2010-10-20 huibong KT -> X-CDN
//#define SMSServAddr "222.122.136.110"
//#define SMSServerHost "sh.0x31.com"
//#define SMSServPort "80"
//#define MaxSizeOfTRxBuffer 1024
#define SMSServAddr "www.x-cdn.com"
#define SMSServerHost "gms.x-cdn.com"
#define SMSServPort "8080"
#define MaxSizeOfTRxBuffer 1024
void SendToWebServ(const char *pszMesg, FILE *shLogFile)
{
char *PostDataEncode(const char *);
char *strURI;
char szSndBuffer[MaxSizeOfTRxBuffer];
char szRcvBuffer[MaxSizeOfTRxBuffer];
char logString[1024];
char sms_admin[32];
int fd, n, k, param_num;
bzero(szSndBuffer, MaxSizeOfTRxBuffer);
bzero(szRcvBuffer, MaxSizeOfTRxBuffer);
strURI = PostDataEncode(pszMesg);
SetIniName(CFGFILE);
GetProfile("SMS_ADMIN", sms_admin, "ADMIN");
snprintf(szSndBuffer, MaxSizeOfTRxBuffer, "GET /sms/send_sms.html?id=%s&msg=%s HTTP/1.0\n"\
"Content-Type: text/plain\n"\
"User-Agent: SeanZilla/1.0\n"\
"Host: %s\n"\
"Connection: close\n"\
"Cache-Control: no-cache\n\n"
, sms_admin, strURI, SMSServerHost);
snprintf(logString, 1024, "[SMS Result]::id=%s :: msg=%s", sms_admin, pszMesg);
WriteSHLog(logString, shLogFile);
/* tcp connection, send, receive */
fd = Tcp_connect(SMSServAddr, SMSServPort);
/* send sndMessage to SMS WEB SERV */
Send(fd, szSndBuffer, strlen(szSndBuffer), 0);
usleep(1);
/* receive result from new sh_statusd */
if ( (n = Recv(fd, szRcvBuffer, strlen(szRcvBuffer), 0)) == 0)
{
#if 0
snprintf(logString, 1024, "[SMS] server : %s", strURI);
WriteSHLog(logString, shLogFile);
#endif
}
free(strURI);
close(fd);
}
char *PostDataEncode(const char *pszCommand)
{
int i = 0;
char tmpBuffer[MaxSizeOfTRxBuffer];
static char *strReturn;
if(pszCommand == NULL)
{
return NULL;
}
while(*pszCommand != '\0')
{
if(*pszCommand == ' ')
{
tmpBuffer[i++] = '+';
*pszCommand++;
}
else if((*pszCommand < '0' && *pszCommand != '-' && *pszCommand != '.' && *pszCommand !='%') ||
(*pszCommand < 'A' && *pszCommand > '9' && *pszCommand !='%') ||
(*pszCommand > 'Z' && *pszCommand < 'a' && *pszCommand != '_' && *pszCommand !='%') ||
(*pszCommand > 'z' && *pszCommand !='%'))
{
tmpBuffer[i++] = '%';
tmpBuffer[i++] = hexchars[(unsigned char)*pszCommand >> 4];
tmpBuffer[i++] = hexchars[(unsigned char)*pszCommand & 15];
*pszCommand++;
}
else if(*pszCommand == '%')
{
tmpBuffer[i++] = '%';
tmpBuffer[i++] = '%';
*pszCommand++;
}
else
{
tmpBuffer[i++] = *pszCommand++;
}
}
tmpBuffer[i] = '\0';
// allocate heap
strReturn = (char *)malloc(strlen(tmpBuffer));
memset(strReturn, 0, strlen(tmpBuffer));
strncpy(strReturn, tmpBuffer, strlen(tmpBuffer)+1);
return strReturn;
}