daemon/conf.c

216 lines
6.3 KiB
C
Raw Permalink Normal View History

2021-12-11 13:20:06 +08:00
#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;
return strndup(p, p0 - p);
}
static void parse_global_module(char *content)
{
char *var, *val_begin, *val_end, *lineEnd;
conf *conf_node = NULL;
2022-01-13 19:18:43 +08:00
char *p1 = NULL, *s = NULL, *t = NULL;
char *p2 = NULL;
2021-12-11 13:20:06 +08:00
while ((lineEnd = set_var_val_lineEnd(content, &var, &val_begin, &val_end)) != NULL) {
if (strcasecmp(var, "PROCESS") == 0) {
conf_node = (conf *)malloc(sizeof(*conf_node));
conf_node->PROCESS = strdup(val_begin);
2022-01-13 19:18:43 +08:00
conf_node->PROCESS_len = val_end - val_begin;
p1 = strstr(val_begin, "->");
for (t = p1; *t != '"'; ++t) ;
conf_node->PROCESS_command = strdup(t + 1);
p2 = strchr(t+1, '\0');
conf_node->PROCESS_command_len = p2 - (t + 1);
for (s = p1 - 1; *s == ' '; s--) {
if (s == val_begin)
return;
}
if (*s == '"')
s--;
conf_node->PROCESS_name = strndup(val_begin, s - val_begin + 1);
conf_node->PROCESS_name_len = s - val_begin + 1;
2021-12-11 13:20:06 +08:00
conf_node->next = NULL;
if (conf_head == NULL) {
conf_head = conf_node;
} else {
conf_node->next = conf_head;
conf_head = conf_node;
}
}
content = strchr(lineEnd + 1, '\n');
}
}
2022-01-13 19:18:43 +08:00
void print_conf(conf * p) {
conf *temp = p; //将temp指针重新指向头结点
while (temp) { //只要temp指针指向的结点的next不是Null就执行输出
if (temp->PROCESS)
printf("%s %d\n", temp->PROCESS, temp->PROCESS_len);
if (temp->PROCESS_name)
printf("%s %d\n", temp->PROCESS_name, temp->PROCESS_name_len);
if (temp->PROCESS_command)
printf("%s %d\n", temp->PROCESS_command, temp->PROCESS_command_len);
temp = temp->next;
}
}
void free_conf(conf *p) {
conf *temp = p;
while (temp) {
if (temp->PROCESS)
free(temp->PROCESS);
if (temp->PROCESS_name)
free(temp->PROCESS_name);
if (temp->PROCESS_command)
free(temp->PROCESS_command);
temp = temp->next;
}
}
2021-12-11 13:20:06 +08:00
void read_conf_link(char *path)
{
char *buff, *global_content;
FILE *file;
long file_size;
/* 读取配置文件到缓冲区 */
file = fopen(path, "r");
2022-01-13 19:18:43 +08:00
if (file == NULL) {
2021-12-11 13:20:06 +08:00
printf("cannot open config file.\n");
2022-01-13 19:18:43 +08:00
exit(1);
}
2021-12-11 13:20:06 +08:00
fseek(file, 0, SEEK_END);
file_size = ftell(file);
buff = (char *)alloca(file_size + 1);
if (buff == NULL)
printf("out of memory.\n");
rewind(file);
fread(buff, file_size, 1, file);
fclose(file);
buff[file_size] = '\0';
/* 读取global模块内容 */
if ((global_content = read_module(buff, "global")) == NULL)
printf("read global module error\n");
parse_global_module(global_content);
free(global_content);
}