Module: check_mk
Branch: master
Commit: 294fc0456e8877f0bcbed7683c48ad29bb1d7d49
URL:
http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=294fc0456e8877…
Author: Mathias Kettner <mk(a)mathias-kettner.de>
Date: Sun Aug 14 12:01:28 2011 +0200
Livestatus: full UTF-8 support
---
ChangeLog | 1 +
livestatus/.f12 | 4 ++
livestatus/src/Query.cc | 113 +++++++++++++++++++++++++++++----------
livestatus/src/data_encoding.h | 32 +++++++++++
livestatus/src/module.c | 13 +++++
5 files changed, 134 insertions(+), 29 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 317afe2..4e57ec9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -100,6 +100,7 @@
MK Livestatus:
* FIX: fix compile problem on Debian unstable (Thanks to Sven Velt)
* Column aggregation (Stats) now also works for perf_data
+ * New configuration variable data_encoding and full UTF-8 support.
1.1.11i1:
Core, Setup, etc.:
diff --git a/livestatus/.f12 b/livestatus/.f12
index ad5157d..693ffad 100755
--- a/livestatus/.f12
+++ b/livestatus/.f12
@@ -10,4 +10,8 @@ fi
make -j 8
+
+SITE=${SITE:-$(omd sites --bare | head -n 1)}
sudo install src/livestatus.o /omd/versions/default/lib/mk-livestatus/livestatus.o
+echo "$C files copied"
+sudo omd restart $SITE nagios
diff --git a/livestatus/src/Query.cc b/livestatus/src/Query.cc
index 4e3c3b9..f089741 100644
--- a/livestatus/src/Query.cc
+++ b/livestatus/src/Query.cc
@@ -42,9 +42,11 @@
#include "Aggregator.h"
#include "OringFilter.h"
#include "waittriggers.h"
+#include "data_encoding.h"
extern int g_debug_level;
extern unsigned long g_max_response_size;
+extern int g_data_encoding;
Query::Query(InputBuffer *input, OutputBuffer *output, Table *table) :
_output(output),
@@ -879,37 +881,90 @@ void Query::outputHostService(const char *host_name, const char
*service_descrip
void Query::outputString(const char *value)
{
- if (!value) {
- if (_output_format != OUTPUT_FORMAT_CSV)
- _output->addBuffer("\"\"", 2);
- return;
- }
+ if (!value) {
+ if (_output_format != OUTPUT_FORMAT_CSV)
+ _output->addBuffer("\"\"", 2);
+ return;
+ }
- else if (_output_format == OUTPUT_FORMAT_CSV)
- _output->addString(value);
+ else if (_output_format == OUTPUT_FORMAT_CSV)
+ _output->addString(value);
- else // JSON
- {
- if (_output_format == OUTPUT_FORMAT_PYTHON)
- _output->addChar('u'); // mark strings as unicode
- _output->addChar('"');
- const char *r = value;
- while (*r) {
- if (*r < 32 && *r >= 0)
- outputUnicodeEscape((unsigned)*r);
- else if ((*r & 0xE0) == 0xC0)
- outputUnicodeEscape(((*r & 31) << 6) | (*++r & 0x3F)); // 2
byte encoding
- else if (*r < 0)
- outputUnicodeEscape((unsigned)((int)*r + 256)); // assume latin1 encoding
- else {
- if (*r == '"' || *r == '\\')
- _output->addChar('\\');
- _output->addChar(*r);
- }
- r++;
- }
- _output->addChar('"');
- }
+ else // JSON
+ {
+ if (_output_format == OUTPUT_FORMAT_PYTHON)
+ _output->addChar('u'); // mark strings as unicode
+ _output->addChar('"');
+ const char *r = value;
+ int chars_left = strlen(r);
+ while (*r) {
+ // Always escape control characters (1..31)
+ if (*r < 32 && *r >= 0)
+ outputUnicodeEscape((unsigned)*r);
+
+ // Output ASCII characters unencoded
+ else if (*r >= 32) {
+ if (*r == '"' || *r == '\\')
+ _output->addChar('\\');
+ _output->addChar(*r);
+ }
+
+ // interprete two-Byte UTF-8 sequences in mode 'utf8' and
'mixed'
+ else if ((g_data_encoding == ENCODING_UTF8 || g_data_encoding ==
ENCODING_MIXED)
+ && ((*r & 0xE0) == 0xC0)) {
+ outputUnicodeEscape(((*r & 31) << 6) | (*(r+1) & 0x3F)); //
2 byte encoding
+ r++;
+ chars_left--;
+ }
+
+ // interprete 3/4-Byte UTF-8 sequences only in mode 'utf8'
+ else if (g_data_encoding == ENCODING_UTF8) {
+ // three-byte sequences (avoid buffer overflow!)
+ if ((*r & 0xF0) == 0xE0) {
+ if (chars_left < 3) {
+ logger(LG_INFO, "Ignoring invalid UTF-8 sequence in string
'%s'", value);
+ break; // end of string. No use in continuing
+ }
+ else {
+ outputUnicodeEscape(
+ ((*r & 0x0F) << 12 |
+ (*(r+1) & 0x3F) << 6 |
+ (*(r+2) & 0x3F)));
+ r += 2;
+ chars_left -= 2;
+ }
+ }
+ // four-byte sequences
+ else if ((*r & 0xF8) == 0xF0) {
+ if (chars_left < 4) {
+ logger(LG_INFO, "Ignoring invalid UTF-8 sequence in string
'%s'", value);
+ break; // end of string. No use in continuing
+ }
+ else {
+ outputUnicodeEscape(
+ ((*r & 0x07) << 18 |
+ (*(r+1) & 0x3F) << 6 |
+ (*(r+2) & 0x3F) << 6 |
+ (*(r+3) & 0x3F)));
+ r += 3;
+ chars_left -= 3;
+ }
+ }
+ else {
+ logger(LG_INFO, "Ignoring invalid UTF-8 sequence in string
'%s'", value);
+ }
+ }
+
+ // in latin1 and mixed mode interprete all other non-ASCII characters as
latin1
+ else {
+ outputUnicodeEscape((unsigned)((int)*r + 256)); // assume latin1
encoding
+ }
+
+ r++;
+ chars_left--;
+ }
+ _output->addChar('"');
+ }
}
void Query::outputBeginList()
diff --git a/livestatus/src/data_encoding.h b/livestatus/src/data_encoding.h
new file mode 100644
index 0000000..79a8d15
--- /dev/null
+++ b/livestatus/src/data_encoding.h
@@ -0,0 +1,32 @@
+// +------------------------------------------------------------------+
+// | ____ _ _ __ __ _ __ |
+// | / ___| |__ ___ ___| | __ | \/ | |/ / |
+// | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
+// | | |___| | | | __/ (__| < | | | | . \ |
+// | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
+// | |
+// | Copyright Mathias Kettner 2010 mk(a)mathias-kettner.de |
+// +------------------------------------------------------------------+
+//
+// This file is part of Check_MK.
+// The official homepage is at
http://mathias-kettner.de/check_mk.
+//
+// check_mk is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by
+// the Free Software Foundation in version 2. check_mk is distributed
+// in the hope that it will be useful, but WITHOUT ANY WARRANTY; with-
+// out even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+// PARTICULAR PURPOSE. See the GNU General Public License for more de-
+// ails. You should have received a copy of the GNU General Public
+// License along with GNU Make; see the file COPYING. If not, write
+// to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+// Boston, MA 02110-1301 USA.
+
+#ifndef data_encoding_h
+#define data_encoding_h
+
+#define ENCODING_UTF8 0
+#define ENCODING_LATIN1 1
+#define ENCODING_MIXED 2
+
+#endif // data_encoding_h
diff --git a/livestatus/src/module.c b/livestatus/src/module.c
index 0735e71..c5b1bbb 100644
--- a/livestatus/src/module.c
+++ b/livestatus/src/module.c
@@ -47,6 +47,7 @@
#include "global_counters.h"
#include "strutil.h"
#include "auth.h"
+#include "data_encoding.h"
#include "waittriggers.h"
#ifndef AF_LOCAL
@@ -89,6 +90,7 @@ int g_thread_running = 0;
int g_thread_pid = 0;
int g_service_authorization = AUTH_LOOSE;
int g_group_authorization = AUTH_STRICT;
+int g_data_encoding = ENCODING_UTF8;
void* voidp;
@@ -602,6 +604,17 @@ void livestatus_parse_arguments(const char *args_orig)
strncat(g_pnp_path, "/", sizeof(g_pnp_path) -
strlen(g_pnp_path) - 1 ); // make sure, that trailing slash is always there
check_pnp_path();
}
+ else if (!strcmp(left, "data_encoding")) {
+ if (!strcmp(right, "utf8"))
+ g_data_encoding = ENCODING_UTF8;
+ else if (!strcmp(right, "latin1"))
+ g_data_encoding = ENCODING_LATIN1;
+ else if (!strcmp(right, "mixed"))
+ g_data_encoding = ENCODING_MIXED;
+ else {
+ logger(LG_INFO, "Invalid data_encoding %s. Allowed are utf8,
latin1 and mixed.", right);
+ }
+ }
else {
logger(LG_INFO, "Ignoring invalid option %s=%s", left, right);
}