denyhosts/conf.c

345 lines
9.7 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "conf.h"
int8_t copy_new_mem(char *src, int src_len, char **dest)
{
*dest = (char *)malloc(src_len + 1);
if (*dest == NULL)
return 1;
memcpy(*dest, src, src_len);
*((*dest) + src_len) = '\0';
return 0;
}
/* 在content中设置变量(var)的首地址,值(val)的位置首地址和末地址,返回下一行指针 */
static char *set_var_val_lineEnd(char *content, char **var, char **val_begin, char **val_end)
{
char *p, *pn, *lineEnd;
;
int val_len;
while (1) {
if (content == NULL)
return NULL;
for (; *content == ' ' || *content == '\t' || *content == '\r' || *content == '\n'; content++) ;
if (*content == '\0')
return NULL;
*var = content;
pn = strchr(content, '\n');
p = strchr(content, '=');
if (p == NULL) {
if (pn) {
content = pn + 1;
continue;
} else
return NULL;
}
content = p;
//将变量以\0结束
for (p--; *p == ' ' || *p == '\t'; p--) ;
*(p + 1) = '\0';
//值的首地址
for (content++; *content == ' ' || *content == '\t'; content++) ;
if (*content == '\0')
return NULL;
//双引号引起来的值支持换行
if (*content == '"') {
*val_begin = content + 1;
*val_end = strstr(*val_begin, "\";");
if (*val_end != NULL)
break;
} else
*val_begin = content;
*val_end = strchr(content, ';');
if (pn && *val_end > pn) {
content = pn + 1;
continue;
}
break;
}
if (*val_end) {
**val_end = '\0';
val_len = *val_end - *val_begin;
lineEnd = *val_end;
} else {
val_len = strlen(*val_begin);
*val_end = lineEnd = *val_begin + val_len;
}
*val_end = *val_begin + val_len;
//printf("var[%s]\nbegin[%s]\n\n", *var, *val_begin);
return lineEnd;
}
static void parse_global_module(char *content, conf * conf)
{
char *var, *val_begin, *val_end, *lineEnd;
int val_begin_len;
while ((lineEnd = set_var_val_lineEnd(content, &var, &val_begin, &val_end)) != NULL) {
if (strcasecmp(var, "DAEMON") == 0) {
val_begin_len = val_end - val_begin;
if (copy_new_mem(val_begin, val_begin_len, &conf->DAEMON) != 0)
return;
}
if (strcasecmp(var, "TIME") == 0) {
val_begin_len = val_end - val_begin;
conf->TIME = atoi(val_begin);
}
if (strcasecmp(var, "IS_BLOCKED") == 0) {
val_begin_len = val_end - val_begin;
conf->IS_BLOCKED = atoi(val_begin);
}
if (strcasecmp(var, "REFUSE_NUMBER") == 0) {
val_begin_len = val_end - val_begin;
conf->REFUSE_NUMBER = atoi(val_begin);
}
if (strcasecmp(var, "IS_MAIL") == 0) {
val_begin_len = val_end - val_begin;
conf->IS_MAIL = atoi(val_begin);
}
if (strcasecmp(var, "IS_DING_WEBHOOK") == 0) {
val_begin_len = val_end - val_begin;
conf->IS_DING_WEBHOOK = atoi(val_begin);
}
if (strcasecmp(var, "PHONE") == 0) {
val_begin_len = val_end - val_begin;
if (copy_new_mem(val_begin, val_begin_len, &conf->PHONE) != 0)
return;
}
if (strcasecmp(var, "DING_WEBHOOK") == 0) {
val_begin_len = val_end - val_begin;
if (copy_new_mem(val_begin, val_begin_len, &conf->DING_WEBHOOK) != 0)
return;
}
if (strcasecmp(var, "IS_QQMAIL") == 0) {
val_begin_len = val_end - val_begin;
conf->IS_QQMAIL = atoi(val_begin);
}
/*
if (strcasecmp(var, "SEND_QQ") == 0) {
val_begin_len = val_end - val_begin;
if (copy_new_mem(val_begin, val_begin_len, &conf->SEND_QQ) != 0)
return;
}
if (strcasecmp(var, "QQMAIL_KEY") == 0) {
val_begin_len = val_end - val_begin;
if (copy_new_mem(val_begin, val_begin_len, &conf->QQMAIL_KEY) != 0)
return;
}
*/
if (strcasecmp(var, "RECV_MAIL") == 0) {
val_begin_len = val_end - val_begin;
if (copy_new_mem(val_begin, val_begin_len, &conf->RECV_MAIL) != 0)
return;
}
if (strcasecmp(var, "PUBLIC_IP") == 0) {
val_begin_len = val_end - val_begin;
if (copy_new_mem(val_begin, val_begin_len, &conf->PUBLIC_IP) != 0)
return;
}
// IP白名单
if (strcasecmp(var, "IPV4_RESTRICTION") == 0) {
val_begin_len = val_end - val_begin;
conf->IPV4_RESTRICTION = atoi(val_begin);
}
if (strcasecmp(var, "IPV4_WHITE_LIST") == 0) {
val_begin_len = val_end - val_begin;
if (copy_new_mem(val_begin, val_begin_len, &conf->IPV4_WHITE_LIST) != 0)
return;
}
// 地域白名单
if (strcasecmp(var, "REGION") == 0) {
val_begin_len = val_end - val_begin;
conf->REGION = atoi(val_begin);
}
if (strcasecmp(var, "REGION_URL") == 0) {
val_begin_len = val_end - val_begin;
if (copy_new_mem(val_begin, val_begin_len, &conf->REGION_URL) != 0)
return;
}
if (strcasecmp(var, "REGION_LIST") == 0) {
val_begin_len = val_end - val_begin;
if (copy_new_mem(val_begin, val_begin_len, &conf->REGION_LIST) != 0)
return;
}
if (strcasecmp(var, "CLAMAV") == 0) {
val_begin_len = val_end - val_begin;
conf->CLAMAV = atoi(val_begin);
}
if (strcasecmp(var, "CLAMAV_TIME") == 0) {
val_begin_len = val_end - val_begin;
conf->CLAMAV_TIME_LEN = val_begin_len;
if (copy_new_mem(val_begin, val_begin_len, &conf->CLAMAV_TIME) != 0)
return;
}
if (strcasecmp(var, "CLAMAV_ARG") == 0) {
val_begin_len = val_end - val_begin;
conf->CLAMAV_TIME_LEN = val_begin_len;
if (copy_new_mem(val_begin, val_begin_len, &conf->CLAMAV_ARG) != 0)
return;
}
content = strchr(lineEnd + 1, '\n');
}
}
/* 在buff中读取模块(global http https httpdns httpudp)内容 */
static char *read_module(char *buff, const char *module_name)
{
int len;
char *p, *p0;
len = strlen(module_name);
p = buff;
while (1)
{
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
p++;
if (strncasecmp(p, module_name, len) == 0)
{
p += len;
while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
p++;
if (*p == '{')
break;
}
if ((p = strchr(p, '\n')) == NULL)
return NULL;
}
if ((p0 = strchr(++p, '}')) == NULL)
return NULL;
return strndup(p, p0 - p);
}
void read_conf(char *filename, conf * configure)
{
char *buff, *global_content;
FILE *file;
long file_size;
int return_val;
file = fopen(filename, "r");
if (file == NULL)
perror("cannot open config file.");
fseek(file, 0, SEEK_END);
file_size = ftell(file);
buff = (char *)alloca(file_size + 1);
if (buff == NULL)
perror("out of memory.");
rewind(file);
if (1 > (return_val = fread(buff, file_size, 1, file)))
perror("fread");
fclose(file);
buff[file_size] = '\0';
if ((global_content = read_module(buff, "global")) == NULL) {
perror("read global module error");
}
parse_global_module(global_content, configure);
free(global_content);
}
void free_conf(conf * conf)
{
if (conf->DAEMON)
free(conf->DAEMON);
if (conf->PHONE)
free(conf->PHONE);
if (conf->DING_WEBHOOK)
free(conf->DING_WEBHOOK);
/*
if (conf->SEND_QQ)
free(conf->SEND_QQ);
if (conf->QQMAIL_KEY)
free(conf->QQMAIL_KEY);
*/
if (conf->RECV_MAIL)
free(conf->RECV_MAIL);
if (conf->PUBLIC_IP)
free(conf->PUBLIC_IP);
if (conf->IPV4_WHITE_LIST)
free(conf->IPV4_WHITE_LIST);
if (conf->REGION_LIST)
free(conf->REGION_LIST);
if (conf->REGION_URL)
free(conf->REGION_URL);
if (conf->CLAMAV_TIME)
free(conf->CLAMAV_TIME);
if (conf->CLAMAV_ARG)
free(conf->CLAMAV_ARG);
return;
}
void ptintf_conf(conf * conf)
{
if (conf->DAEMON)
printf("%s\n", conf->DAEMON);
printf("%d\n", conf->TIME);
printf("%d\n", conf->REFUSE_NUMBER);
printf("%d\n", conf->IS_MAIL);
printf("%d\n", conf->IS_DING_WEBHOOK);
if (conf->PHONE)
printf("%s\n", conf->PHONE);
if (conf->DING_WEBHOOK)
printf("%s\n", conf->DING_WEBHOOK);
printf("%d\n", conf->IS_QQMAIL);
/*
if (conf->SEND_QQ)
printf("%s\n", conf->SEND_QQ);
if (conf->QQMAIL_KEY)
printf("%s\n", conf->QQMAIL_KEY);
*/
if (conf->RECV_MAIL)
printf("%s\n", conf->RECV_MAIL);
if (conf->PUBLIC_IP)
printf("%s\n", conf->PUBLIC_IP);
printf("%d\n", conf->IPV4_RESTRICTION);
if (conf->IPV4_WHITE_LIST)
printf("%s\n", conf->IPV4_WHITE_LIST);
printf("%d\n", conf->REGION);
if (conf->REGION_LIST)
printf("%s\n", conf->REGION_LIST);
}
void split_string(char string[], char delims[], char (*whitelist_ip)[WHITELIST_IP_NUM])
{
int i = 0;
char *result = NULL;
result = strtok(string, delims);
while (result != NULL)
{
i++;
strcpy(whitelist_ip[i], result);
result = strtok(NULL, delims);
}
}