#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; char *p1 = NULL, *s = NULL, *t = NULL; char *p2 = NULL; 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); 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; 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'); } } 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; } } void read_conf_link(char *path) { char *buff, *global_content; FILE *file; long file_size; /* 读取配置文件到缓冲区 */ file = fopen(path, "r"); if (file == NULL) { printf("cannot open config file.\n"); exit(1); } 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); }