1 首先找到中文乱码页面的相关cgi,以status.cgi为例,在对应的cgi/status.c里面找到展示services的部分(nagios3.3.1源码)
1780 /* the rest of the columns... */
1781 printf("<TD CLASS='status%s'>%s</TD>\n", status_class, status);
1782 printf("<TD CLASS='status%s' nowrap>%s</TD>\n", status_bg_class, date_time);
1783 printf("<TD CLASS='status%s' nowrap>%s</TD>\n", status_bg_class, state_duration);
1784 printf("<TD CLASS='status%s'>%d/%d</TD>\n", status_bg_class, temp_status->current_attempt, temp_status->max_attempts);
1785 printf("<TD CLASS='status%s' valign='center'>", status_bg_class);
1786 printf("%s ", (temp_status->plugin_output == NULL) ? "" : html_encode(temp_status->plugin_output, TRUE));
1780 行是在打印 Status 的数据;
1781 行是在打印 Last Check 的数据;
1782行是在打印 Duration 的数据;
1783 行是在打印 Attempt 的数据;
1785~1786 行是在打印 Status Information 的数据;
我们需要注意的是1786行:为什么我们的插件输出被 html_encode 了?这个函数究竟做了什么?
2 在 include/cgiutils.h 中找到 html_encode 函数
451 char * html_encode(char *, int); /* encodes a string in HTML format (for what the user sees) */
3 在cgi/cgiutils.c 中找到 html_encode 的实现
950 /* escapes a string used in HTML */
951 char * html_encode(char *input, int escape_newlines) {
952 int len, output_len;
953 int x, y;
954 char temp_expansion[10];
...
1015 /* for simplicity, all other chars represented by their numeric value */
1016 else {
1017 if(escape_html_tags == FALSE)
1018 encoded_html_string[y++] = input[x];
1019 else {
1020 encoded_html_string[y] = '\x0';
1021 sprintf(temp_expansion, "&#%d;", (unsigned char)input[x]);
1022 if((int)strlen(encoded_html_string) < (output_len - strlen(temp_expansion))) {
1023 strcat(encoded_html_string, temp_expansion);
1024 y += strlen(temp_expansion);
1025 }
1026 }
1027 }
...
1032 return encoded_html_string;
}
看1015行注释,for simplicity, all other chars represented by their numeric value。简单地,除去之前已处理的其他字符(包括中文)转化为数字。这里是中文乱码的关键。
4 这样解决方法有以下几种
- 修改配置文件etc/cgi.cfg中参数escape_html_tags的值1→0,禁止其他字符转为数字。
- 修改源代码中html_encode函数,对中文进行处理。