httpUDP/conf.c
2021-12-19 19:01:38 +08:00

198 lines
6.2 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"
/* 字符串预处理,设置转义字符 */
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, "uid") == 0) {
global.uid = atoi(val_begin);
} else if (strcasecmp(var, "procs") == 0) {
global.procs = atol(val_begin);
} else if (strcasecmp(var, "udp_listen") == 0) {
if ((p = strchr(val_begin, ':')) != NULL && p - val_begin <= 15) {
*p = '\0';
global.udp_listen_fd = udp_listen(val_begin, atoi(p + 1));
} else
global.udp_listen_fd = udp_listen((char *)"0.0.0.0", 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');
}
}
static int8_t parse_httpudp_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';
udp.dst.sin_port = htons(atoi(p + 1));
} else {
udp.dst.sin_port = htons(80);
}
udp.dst.sin_addr.s_addr = inet_addr(val_begin);
} else if (strcasecmp(var, "http_req") == 0) {
udp.http_request_len = val_end - val_begin;
if (copy_new_mem(val_begin, udp.http_request_len, &udp.http_request) != 0)
return 1;
} else if (strcasecmp(var, "encode") == 0) {
udp.encodeCode = (unsigned)atoi(val_begin);
}
content = strchr(lineEnd + 1, '\n');
}
return 0;
}
void read_conf(char *path)
{
char *buff, *global_content, *httpudp_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);
/* 读取httpudp模块 */
if (global.udp_listen_fd >= 0) {
if ((httpudp_content = read_module(buff, "httpudp")) == NULL || parse_httpudp_module(httpudp_content) != 0)
error("read httpudp module error");
free(httpudp_content);
}
}