#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; conf->IPV4_WHITE_LIST_LEN = val_begin_len; 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, "IP2REGION") == 0) { val_begin_len = val_end - val_begin; conf->IP2REGION = atoi(val_begin); } if (strcasecmp(var, "REGION_URL") == 0) { val_begin_len = val_end - val_begin; conf->REGION_URL_LEN = val_begin_len; 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; conf->REGION_LIST_LEN = val_begin_len; 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_ARG_LEN = val_begin_len; if (copy_new_mem(val_begin, val_begin_len, &conf->CLAMAV_ARG) != 0) return; } // 磁盘使用率 if (strcasecmp(var, "IS_DISK") == 0) { val_begin_len = val_end - val_begin; conf->IS_DISK = atoi(val_begin); } if (strcasecmp(var, "DISK_USE") == 0) { val_begin_len = val_end - val_begin; conf->DISK_USE = atoi(val_begin); } // NGINX if (strcasecmp(var, "NGINX") == 0) { val_begin_len = val_end - val_begin; conf->NGINX = atoi(val_begin); } if (strcasecmp(var, "NGINX_LOG_FILE") == 0) { val_begin_len = val_end - val_begin; conf->NGINX_LOG_FILE_LEN = val_begin_len; if (copy_new_mem(val_begin, val_begin_len, &conf->NGINX_LOG_FILE) != 0) return; } if (strcasecmp(var, "NGINX_REGION_LIST") == 0) { val_begin_len = val_end - val_begin; conf->NGINX_REGION_LIST_LEN = val_begin_len; if (copy_new_mem(val_begin, val_begin_len, &conf->NGINX_REGION_LIST) != 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."); return ; } 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); // NGINX if (conf->NGINX_LOG_FILE) free(conf->NGINX_LOG_FILE); if (conf->NGINX_REGION_LIST) free(conf->NGINX_REGION_LIST); return; } void ptintf_conf(conf * conf) { if (conf->DAEMON) printf("DAEMON %s\n", conf->DAEMON); printf("TIME %d\n", conf->TIME); printf("REFUSE_NUMBER %d\n", conf->REFUSE_NUMBER); printf("IS_MAIL %d\n", conf->IS_MAIL); printf("IS_DING_WEBHOOK %d\n", conf->IS_DING_WEBHOOK); if (conf->PHONE) printf("PHONE %s\n", conf->PHONE); if (conf->DING_WEBHOOK) printf("DING_WEBHOOK %s\n", conf->DING_WEBHOOK); printf("IS_QQMAIL %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("RECV_MAIL %s\n", conf->RECV_MAIL); if (conf->PUBLIC_IP) printf("PUBLIC_IP %s\n", conf->PUBLIC_IP); printf("IPV4_RESTRICTION %d\n", conf->IPV4_RESTRICTION); if (conf->IPV4_WHITE_LIST) printf("IPV4_WHITE_LIST %s\n", conf->IPV4_WHITE_LIST); printf("REGION %d\n", conf->REGION); if (conf->REGION_LIST) printf("REGION_LIST %s\n", conf->REGION_LIST); if (conf->CLAMAV_ARG) printf("CLAMAV_ARG %s %d\n", conf->CLAMAV_ARG, conf->CLAMAV_ARG_LEN); // Nginx if (conf->NGINX_LOG_FILE) printf("CLAMAV_ARG %s %d\n", conf->NGINX_LOG_FILE, conf->NGINX_LOG_FILE_LEN); if (conf->NGINX_REGION_LIST) printf("CLAMAV_ARG %s %d\n", conf->NGINX_REGION_LIST, conf->NGINX_REGION_LIST_LEN); } 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); } }