222 lines
7.1 KiB
C
222 lines
7.1 KiB
C
|
#include "conf.h"
|
|||
|
|
|||
|
/* 字符串预处理,设置转义字符 */
|
|||
|
static void string_pretreatment(char *str, int *len)
|
|||
|
{
|
|||
|
char *lf, *p, *ori_strs[] = { "\\r", "\\n", "\\b", "\\v", "\\f", "\\t", "\\a", "\\b", "\\0" }, to_chrs[] = { '\r', '\n', '\b', '\v', '\f', '\t', '\a', '\b', '\0' };
|
|||
|
int i;
|
|||
|
|
|||
|
while ((lf = strchr(str, '\n')) != NULL) {
|
|||
|
for (p = lf + 1; *p == ' ' || *p == '\t' || *p == '\n' || *p == '\r'; p++)
|
|||
|
*len -= 1;
|
|||
|
strcpy(lf, p);
|
|||
|
*len -= 1;
|
|||
|
}
|
|||
|
for (i = 0; i < sizeof(to_chrs); i++) {
|
|||
|
for (p = strstr(str, ori_strs[i]); p; p = strstr(p, ori_strs[i])) {
|
|||
|
//支持\\r
|
|||
|
*(p - 1) == '\\' ? (*p--) : (*p = to_chrs[i]);
|
|||
|
memmove(p + 1, p + 2, strlen(p + 2));
|
|||
|
(*len)--;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* 在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;
|
|||
|
}
|
|||
|
string_pretreatment(*val_begin, &val_len);
|
|||
|
*val_end = *val_begin + val_len;
|
|||
|
//printf("var[%s]\nbegin[%s]\n\n", *var, *val_begin);
|
|||
|
return lineEnd;
|
|||
|
}
|
|||
|
|
|||
|
/* 在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;
|
|||
|
|
|||
|
//printf("%s\n%s", module_name, content);
|
|||
|
return strndup(p, p0 - p);
|
|||
|
}
|
|||
|
|
|||
|
static void parse_global_module(char *content)
|
|||
|
{
|
|||
|
char *var, *val_begin, *val_end, *lineEnd, *p;
|
|||
|
|
|||
|
while ((lineEnd = set_var_val_lineEnd(content, &var, &val_begin, &val_end)) != NULL) {
|
|||
|
if (strcasecmp(var, "mode") == 0) {
|
|||
|
if (strcasecmp(val_begin, "wap_connect") == 0)
|
|||
|
global.mode = WAP_CONNECT;
|
|||
|
else if (strcasecmp(val_begin, "wap") == 0)
|
|||
|
global.mode = WAP;
|
|||
|
else if (strcasecmp(val_begin, "net_connect") == 0)
|
|||
|
global.mode = NET_CONNECT;
|
|||
|
else if (strcasecmp(val_begin, "net_proxy") == 0)
|
|||
|
global.mode = NET_PROXY;
|
|||
|
} else if (strcasecmp(var, "uid") == 0) {
|
|||
|
global.uid = atoi(val_begin);
|
|||
|
} else if (strcasecmp(var, "procs") == 0) {
|
|||
|
global.procs = atol(val_begin);
|
|||
|
}
|
|||
|
|
|||
|
else if (strcasecmp(var, "dns_listen") == 0) {
|
|||
|
if ((p = strchr(val_begin, ':')) != NULL && p - val_begin <= 15) {
|
|||
|
*p = '\0';
|
|||
|
global.dns_listen_fd = udp_listen(val_begin, atoi(p + 1));
|
|||
|
} else
|
|||
|
global.dns_listen_fd = udp_listen((char *)"127.0.0.1", atoi(val_begin));
|
|||
|
}
|
|||
|
|
|||
|
else if (strcasecmp(var, "strict") == 0 && strcasecmp(val_begin, "on") == 0) {
|
|||
|
global.strict_modify = 1;
|
|||
|
} else if (strcasecmp(var, "timeout") == 0) {
|
|||
|
global.timeout_m = atoi(val_begin);
|
|||
|
}
|
|||
|
|
|||
|
content = strchr(lineEnd + 1, '\n');
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* 读取HTTPDNS模块 */
|
|||
|
static int8_t parse_httpdns_module(char *content)
|
|||
|
{
|
|||
|
char *var, *val_begin, *val_end, *lineEnd, *p;
|
|||
|
|
|||
|
while ((lineEnd = set_var_val_lineEnd(content, &var, &val_begin, &val_end)) != NULL) {
|
|||
|
if (strcasecmp(var, "addr") == 0) {
|
|||
|
if ((p = strchr(val_begin, ':')) != NULL && p - val_begin <= 15) {
|
|||
|
*p = '\0';
|
|||
|
httpdns.dst.sin_port = htons(atoi(p + 1));
|
|||
|
} else {
|
|||
|
httpdns.dst.sin_port = htons(80);
|
|||
|
}
|
|||
|
httpdns.dst.sin_addr.s_addr = inet_addr(val_begin);
|
|||
|
} else if (strcasecmp(var, "mode") == 0 && strcasecmp(val_begin, "tcpDNS") == 0) {
|
|||
|
httpdns.tcpDNS_mode = 1;
|
|||
|
} else if (strcasecmp(var, "http_req") == 0) {
|
|||
|
httpdns.http_req_len = val_end - val_begin;
|
|||
|
if (copy_new_mem(val_begin, httpdns.http_req_len, &httpdns.http_req) != 0)
|
|||
|
return 1;
|
|||
|
} else if (strcasecmp(var, "cachePath") == 0) {
|
|||
|
httpdns.cachePath = strdup(val_begin);
|
|||
|
if (httpdns.cachePath == NULL || read_cache_file() != 0)
|
|||
|
return 1;
|
|||
|
} else if (strcasecmp(var, "cacheLimit") == 0) {
|
|||
|
httpdns.cacheLimit = atoi(val_begin);
|
|||
|
} else if (strcasecmp(var, "encode") == 0) {
|
|||
|
httpdns.encodeCode = (unsigned)atoi(val_begin);
|
|||
|
}
|
|||
|
|
|||
|
content = strchr(lineEnd + 1, '\n');
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
void read_conf(char *path)
|
|||
|
{
|
|||
|
char *buff, *global_content, *httpdns_content;
|
|||
|
FILE *file;
|
|||
|
long file_size;
|
|||
|
|
|||
|
/* 读取配置文件到缓冲区 */
|
|||
|
file = fopen(path, "r");
|
|||
|
if (file == NULL)
|
|||
|
error("cannot open config file.");
|
|||
|
fseek(file, 0, SEEK_END);
|
|||
|
file_size = ftell(file);
|
|||
|
buff = (char *)alloca(file_size + 1);
|
|||
|
if (buff == NULL)
|
|||
|
error("out of memory.");
|
|||
|
rewind(file);
|
|||
|
fread(buff, file_size, 1, file);
|
|||
|
fclose(file);
|
|||
|
buff[file_size] = '\0';
|
|||
|
/* 读取global模块内容 */
|
|||
|
if ((global_content = read_module(buff, "global")) == NULL)
|
|||
|
error("read global module error");
|
|||
|
parse_global_module(global_content);
|
|||
|
free(global_content);
|
|||
|
|
|||
|
/* 读取httpdns模块 */
|
|||
|
if (global.dns_listen_fd >= 0) {
|
|||
|
if ((httpdns_content = read_module(buff, "httpdns")) == NULL || parse_httpdns_module(httpdns_content) != 0)
|
|||
|
error("read httpdns module error");
|
|||
|
free(httpdns_content);
|
|||
|
}
|
|||
|
|
|||
|
}
|